I have made an Image Editor and it works fine. Now, in my recent edits page, I added a feature select multiple items. But, I get a strange behaviour when I refresh the recycler view. See this ->
https://www.veed.io/view/43fa65a4-24e6-44e8-8cea-468ca8c62d7a.
This is my adapter code ->
public class RecentsAdapter extends RecyclerView.Adapter<RecentsAdapter.ViewHolder>{
private List<ImageFile> files;
private final PopupListener popupListener;
RecentItemListeners recentItemListeners;
public Integer selectedItemsCount = 0;
TextView neEditsTV;
public RecentsAdapter(List<ImageFile> files, PopupListener popupListener, RecentItemListeners listeners, TextView neEditsTV) {
this.files = files;
this.popupListener = popupListener;
this.recentItemListeners = listeners;
this.neEditsTV = neEditsTV;
}
public void updateList(List<ImageFile> filesList){
if (files.size() < filesList.size()){
int dif = filesList.size() - files.size();
this.files = filesList;
for (int i = 0; i < dif; i++) {
notifyItemInserted(i);
}
}else if (files.size() > filesList.size()){
for (int i = 0; i < filesList.size(); i++) {
notifyItemChanged(i);
}
notifyDataSetChanged();
notify();
}else {
this.files = filesList;
for (int i = 0; i < filesList.size(); i++) {
notifyItemChanged(i);
}
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(ItemRecentBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
#SuppressLint("NewApi")
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.setData(files.get(position));
}
#Override
public int getItemCount() {
return files.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements TinyDBManager.ValueChangeListener {
ItemRecentBinding binding;
boolean mIsSelected = false;
public ViewHolder(#NonNull ItemRecentBinding itemView) {
super(itemView.getRoot());
binding = itemView;
}
#SuppressLint({"ClickableViewAccessibility", "ResourceAsColor"})
#RequiresApi(api = Build.VERSION_CODES.Q)
public void setData(ImageFile file){
TinyDBManager tinyDBManager = TinyDB.getInstance(itemView.getContext());
tinyDBManager.setValueChangeListener(this);
binding.fileName.setText(file.getName());
binding.preview.setImageURI(Uri.parse(file.getPath()));
Log.d("positionChecker",getAdapterPosition() + "");
#SuppressLint("SimpleDateFormat") String datept1 = new SimpleDateFormat("dd/MM/yyyy").format(file.getLastModified());
#SuppressLint("SimpleDateFormat") String datept3 = new SimpleDateFormat("hh:mm:ss a").format(file.getLastModified());
binding.lastEdited.setText(datept1 + " at " + datept3);
binding.option.setOnClickListener(v -> {
ContextThemeWrapper contextWrapper = new ContextThemeWrapper(itemView.getContext(),R.style.Theme_ImageEditor);
PopupMenu menu = new PopupMenu(contextWrapper, binding.option);
menu.inflate(R.menu.recent_item_menu);
menu.setForceShowIcon(true);
menu.show();
menu.setOnDismissListener(menu1 -> popupListener.onPopupClosed());
popupListener.onPopupOpened();
menu.setOnMenuItemClickListener(item -> {
switch (item.getTitle().toString()){
case "Open":
Intent openIntent = new Intent();
openIntent.setAction(Intent.ACTION_VIEW);
openIntent.setDataAndType(Uri.parse(file.getPath()), "image/*");
openIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
itemView.getContext().startActivity(openIntent);
break;
case "Share":
Intent shareIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse(file.getPath());
shareIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
shareIntent.setType("image/*");
itemView.getContext().startActivity(Intent.createChooser(shareIntent, "Share image via..."));
break;
case "Edit":
Intent editIntent = new Intent(itemView.getContext(), ImageEditorActivity.class);
editIntent.putExtra("filePath",file.getPath());
editIntent.putExtra("position",getAdapterPosition());
Toast.makeText(contextWrapper, "" + file.getName(), Toast.LENGTH_SHORT).show();
editIntent.putExtra("name",file.getName());
editIntent.putExtra("new",false);
v.getContext().startActivity(editIntent);
break;
case "Remove from list":
TinyDBManager tinyDB = TinyDB.getInstance(v.getContext());
List<ImageFile> imageFiles = tinyDB.get("files",null);
imageFiles.remove(getAdapterPosition());
files.remove(getAdapterPosition());
tinyDB.put("files",imageFiles);
notifyItemRemoved(getAdapterPosition());
break;
case "Delete":
CustomAlertDialog dialog = new CustomAlertDialog(itemView.getContext(),null);
View.OnClickListener[] clickListeners = new View.OnClickListener[2];
clickListeners[0] = v1 -> dialog.dismiss();
clickListeners[1] = v1 -> {
dialog.dismiss();
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + file.getName();
boolean deleteFile = new File(path).delete();
Log.d("path:",file.getPath());
if (deleteFile)
Toast.makeText(contextWrapper, "success", Toast.LENGTH_SHORT).show();
else Toast.makeText(contextWrapper, "fail", Toast.LENGTH_SHORT).show();
MediaScannerConnection.scanFile(itemView.getContext(), new String[] { Environment.getExternalStorageDirectory().toString() }, null, (path1, uri) -> {
Log.i("ExternalStorage", "Scanned " + path1 + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
});
};
dialog.show(itemView.getContext(), "Delete image","Are you sure you want to delete the image?\nThis action cannot be reverted.", new String[]{"No","Yes"},clickListeners);
}
return true;
});
});
binding.share.setOnClickListener(v -> {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
Uri screenshotUri = Uri.parse(file.getPath());
shareIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
shareIntent.setType("image/*");
itemView.getContext().startActivity(Intent.createChooser(shareIntent, "Share image via..."));
});
binding.getRoot().setOnClickListener(v -> {
if (selectedItemsCount != 0) {
if (mIsSelected) {
mIsSelected = false;
selectedItemsCount--;
binding.getRoot().setCardBackgroundColor(Color.WHITE);
binding.lastEdited.setTextColor(Color.GRAY);
binding.fileName.setTextColor(Color.BLACK);
binding.option.setImageTintList(ColorStateList.valueOf(Color.GRAY));
recentItemListeners.onItemClick(getAdapterPosition(), 1, file.getPath(),file);
} else {
recentItemListeners.onItemClick(getAdapterPosition(), 0, file.getPath(),file);
binding.getRoot().setCardBackgroundColor(itemView.getContext().getColor(R.color.primary));
binding.lastEdited.setTextColor(Color.WHITE);
binding.fileName.setTextColor(Color.WHITE);
binding.option.setImageTintList(ColorStateList.valueOf(Color.WHITE));
mIsSelected = true;
selectedItemsCount++;
}
}else {
mIsSelected = false;
binding.getRoot().setCardBackgroundColor(Color.WHITE);
binding.lastEdited.setTextColor(Color.GRAY);
binding.fileName.setTextColor(Color.BLACK);
binding.option.setImageTintList(ColorStateList.valueOf(Color.GRAY));
}
});
binding.getRoot().setOnLongClickListener(v -> {
mIsSelected = true;
binding.getRoot().setCardBackgroundColor(itemView.getContext().getColor(R.color.primary));
binding.lastEdited.setTextColor(Color.WHITE);
binding.fileName.setTextColor(Color.WHITE);
binding.option.setImageTintList(ColorStateList.valueOf(Color.WHITE));
recentItemListeners.onItemLongClick(getAdapterPosition(), file.getPath(), file);
selectedItemsCount++;
return true;
});
}
#Override
public <E> void onValueAdded(String key, E value) {
files = (List<ImageFile>) value;
files.sort(Comparator.comparing(obj -> obj.getLastModified()));
Collections.reverse(files);
notifyDataSetChanged();
neEditsTV.setVisibility(files.size() == 0 ? View.VISIBLE : View.GONE);
}
#Override
public void onKeyRemoved(String key) {
}
#Override
public void onAllKeysRemoved() {
}
}
}
And now my activity interface listener which are passed to the adapter ->
#Override
public void onItemClick(int position, int action, String filePath, ImageFile file) {
if (selectedItems.contains(file) && action == 1) {
selectedItemsCount--;
filePaths.remove(position);
selectedItems.remove(selectedItems.get(position));
if (selectedItemsCount == 0){
binding.toolbar.setTitle(getString(R.string.app_name));
binding.toolbar.getMenu().clear();
binding.toolbar.setNavigationIcon(null);
canUpdate = true;
}else {
binding.toolbar.setTitle("" + selectedItemsCount);
binding.toolbar.getMenu().clear();
binding.toolbar.inflateMenu(R.menu.multi_select_options);
binding.toolbar.setNavigationIcon(R.drawable.left);
canUpdate = false;
}
}else {
selectedItemsCount++;
selectedItems.add(file);
filePaths.add(filePath);
binding.toolbar.setTitle(selectedItemsCount + " Selected");
binding.toolbar.getMenu().clear();
binding.toolbar.inflateMenu(R.menu.multi_select_options);
binding.toolbar.setNavigationIcon(R.drawable.left);
canUpdate = false;
}
}
#Override
public void onItemLongClick(int position, String filePath, ImageFile file) {
if (selectedItems.contains(file)) return;
selectedItemsCount++;
selectedItems.add(file);
filePaths.add(filePath);
binding.toolbar.setTitle(selectedItemsCount + " Selected");
binding.toolbar.getMenu().clear();
binding.toolbar.inflateMenu(R.menu.multi_select_options);
binding.toolbar.setNavigationIcon(R.drawable.left);
canUpdate = false;
}
And my item file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/_65sdp"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:cardCornerRadius="#dimen/_6sdp"
android:padding="#dimen/_10sdp"
app:cardElevation="2dp"
android:layout_marginTop="#dimen/_12sdp"
android:layout_marginHorizontal="#dimen/_6sdp"
android:background="?selectableItemBackground">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="?selectableItemBackground">
<ImageView
android:id="#+id/preview"
android:layout_width="#dimen/_70sdp"
android:layout_height="match_parent"
tools:src="#tools:sample/backgrounds/scenic"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:layout_marginStart="#dimen/_10sdp"
android:paddingVertical="#dimen/_2sdp"
android:gravity="center">
<TextView
android:id="#+id/fileName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sample file.png"
style="#style/TextAppearance.AppCompat.Title"
android:gravity="center_vertical"
android:ellipsize="end"
android:maxLines="1"
android:layout_weight="1"/>
<TextView
android:id="#+id/lastEdited"
style="#style/TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="Sample file.png"
android:textColor="#android:color/darker_gray"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/option"
android:layout_width="#dimen/_24sdp"
android:layout_height="0dp"
android:src="#drawable/more_vert"
android:padding="#dimen/_2sdp"
android:background="?selectableItemBackgroundBorderless"
app:tint="#android:color/darker_gray"
android:layout_weight="1"/>
<ImageView
android:id="#+id/share"
android:layout_width="#dimen/_24sdp"
android:layout_height="0dp"
android:src="#drawable/share"
android:padding="#dimen/_2sdp"
android:background="?selectableItemBackgroundBorderless"
app:tint="#android:color/holo_red_light"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
How can I prevent this behaviour?
Related
fragment_picture.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:id="#+id/picture_fragment"
android:layout_height="match_parent"
android:background="#F1F1F1">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcv_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:spanCount="1"
android:visibility="gone"
tools:listitem="#layout/item_picture" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<androidx.constraintlayout.widget.Group
android:id="#+id/group_no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="imv_no_data,tv_no_data" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/imv_no_data"
android:layout_width="#dimen/_100sdp"
android:layout_height="#dimen/_100sdp"
android:layout_marginBottom="#dimen/_12sdp"
android:padding="#dimen/_8sdp"
android:src="#drawable/ic_no_image"
app:layout_constraintBottom_toTopOf="#id/tv_no_data"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tv_no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/_16sdp"
android:text="#string/no_image"
android:textColor="#color/color_828282"
android:textSize="#dimen/_14sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:visibility="gone"
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_16sdp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_no_data" />
</androidx.constraintlayout.widget.ConstraintLayout>
FragmentPicture.java
public class PictureFragment extends BaseFragment<FragmentPictureBinding> {
private static final int REQUEST_PERMISSION_DELETE = 376;
private PictureAdapter pictureAdapter;
private int pos;
SwipeRefreshLayout swipeRefresh;
#Override
protected void initView() {
pictureAdapter = new PictureAdapter(new ArrayList<>(), getContext());
pictureAdapter.setCallBackAdapter(item -> openMedia(item.getPath()));
pictureAdapter.setCallBackPicture(new PictureAdapter.CallBackPicture() {
#Override
public void onClickMore(String s, int adapterPosition, View v) {
showPopupMenuMore(s, adapterPosition, v);
}
});
binding.rcvPicture.setAdapter(pictureAdapter);
binding.swipeRefresh.setOnRefreshListener(() -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
getData();
}else {
if (getActivity() instanceof MainActivity){
((MainActivity) getActivity()).askPermissionStorageMain();
}
}
} else {
getData();
}
binding.swipeRefresh.setRefreshing(false);
});
binding.swipeRefresh.setColorSchemeResources(R.color.color_accent,
android.R.color.holo_green_dark,
android.R.color.holo_orange_dark,
android.R.color.holo_blue_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
getData();
}
} else {
getData();
}
}
public void onCLickMore(String item, int pos, View view) {
showPopupMenuMore(item, pos, view);
}
private void showPopupMenuMore(String item, int pos, View view) {
PopupMenu popupMenu = new PopupMenu(getContext(), view);
popupMenu.inflate(R.menu.popup_menu_more_picture);
popupMenu.show();
// popupMenu.getMenu().getItem(1).setEnabled(PreferencesHelper.getBoolean(PreferencesHelper.KEY_SAVE_AS_GIF, true));
popupMenu.setOnMenuItemClickListener(menuItem ->{
switch (menuItem.getItemId()) {
case R.id.share_picture:
shareMedia(item);
break;
case R.id.delete_picture:
this.pos = pos;
deletePhoto(item);
break;
}
return true;
});
}
private void getData() {
getAllFilesInPicture()
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(this::mapFiles)
.subscribe(datas -> {
if (datas.isEmpty()) {
binding.rcvPicture.setVisibility(View.GONE);
binding.groupNoData.setVisibility(View.VISIBLE);
} else {
binding.rcvPicture.setVisibility(View.VISIBLE);
binding.groupNoData.setVisibility(View.GONE);
pictureAdapter.addDatas(datas);
}
},throwable -> {
});
}
public Single<File[]> getAllFilesInPicture() {
return Single.create(sub -> {
File[] listFile = Storage.getFilesImageInStorage(requireContext());
if (listFile != null) {
sub.onSuccess(listFile);
} else {
sub.onSuccess(new File[]{});
}
});
}
public Single<List<VideoFile>> mapFiles(#NonNull File[] listFile) {
return Single.create(sub -> {
long previousDate = 0;
List<VideoFile> videoFiles = new ArrayList<>();
Arrays.sort(listFile, (f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified()));
List<String> pictureFile = new ArrayList<>();
for (int i = listFile.length - 1; i >= 0; i--) {
VideoFile videoFile = new VideoFile();
if (!Toolbox.isSameDay(previousDate, listFile[i].lastModified())) {
VideoFile header = new VideoFile();
header.setHeader(true);
header.setLastModified(listFile[i].lastModified());
videoFiles.add(header);
}
videoFile.setPath(listFile[i].getAbsolutePath());
videoFile.setName(listFile[i].getName());
videoFile.setSize(listFile[i].length());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(new File(listFile[i].getPath()).getAbsolutePath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
videoFile.setResolution(imageWidth+"x"+imageHeight);
videoFile.setSize(listFile[i].length());
videoFile.setLastModified(listFile[i].lastModified());
videoFiles.add(videoFile);
previousDate = listFile[i].lastModified();
pictureFile.add(listFile[i].getAbsolutePath());
}
sub.onSuccess(videoFiles);
});
}
#Override
protected void initControl() {
}
private void itemToItem(String filepath){
}
private void openMedia(String filePath) {
Uri fileUri = FileProvider.getUriForFile(
getContext(), getContext().getPackageName() + ".provider",
new File(filePath));
try {
Intent openVideoIntent = new Intent();
openVideoIntent.setAction(Intent.ACTION_VIEW)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK)
.setDataAndType(
fileUri,
getContext().getContentResolver().getType(fileUri));
getContext().startActivity(openVideoIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
private void shareMedia(String filePath) {
Uri fileUri = FileProvider.getUriForFile(
getContext(), getContext().getPackageName() + ".provider",
new File(filePath));
Intent shareIntent = new Intent()
.setAction(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_STREAM, fileUri)
.setType(filePath.endsWith(".mp4") ? "video/mp4" : "image/*");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(shareIntent);
}
protected void deletePhoto(String path) {
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
alert.setTitle("Delete");
alert.setMessage("Do you want to delete this image ?");
alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//This will delete my Image from recycleView
deleteMedia(path);
//I Wan't to add here code for refreshing recycle view
}
});
alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alert.show();
}
private void deleteMedia(String filePath) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
new File(filePath).delete();
//removeItem(pos);
MediaScannerConnection.scanFile(getActivity(),
new String[]{filePath}, new String[]{"video/mp4"},
(path1, uri) -> {
});
} else {
MediaScannerConnection.scanFile(getActivity(),
new String[]{filePath}, new String[]{"video/mp4"},
(path1, uri) -> {
if (uri != null) {
try {
if (getActivity().getContentResolver().delete(uri, null, null) != -1) {
//removeItem(pos);
}
swipeRefresh.setRefreshing(false);
} catch (SecurityException e) {
List<Uri> uris = new ArrayList<>();
uris.add(uri);
requestDeletePermission(uris);
}
}
});
}
}
private void requestDeletePermission(List<Uri> uriList) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
PendingIntent pi = MediaStore.createDeleteRequest(getActivity().getContentResolver(), uriList);
startIntentSenderForResult(pi.getIntentSender(), REQUEST_PERMISSION_DELETE, null, 0, 0,
0, null);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
}
private void removeItem(int pos) {
getBaseActivity().runOnUiThread(() -> {
pictureAdapter.getList().remove(pos);
pictureAdapter.notifyItemRemoved(pos);
if (pictureAdapter.getList().get(pictureAdapter.getList().size() - 1).isHeader()) {
pictureAdapter.getList().remove(pictureAdapter.getList().size() - 1);
pictureAdapter.notifyItemRemoved(pictureAdapter.getList().size() - 1);
}
if (pictureAdapter.getList().isEmpty()) {
binding.rcvPicture.setVisibility(View.GONE);
binding.groupNoData.setVisibility(View.VISIBLE);
binding.progress.setVisibility(View.GONE);
} else {
binding.rcvPicture.setVisibility(View.VISIBLE);
binding.groupNoData.setVisibility(View.GONE);
}
//Have?
});
}
#Override
protected boolean isNeedRefresh() {
return true;
}
#Override
protected FragmentPictureBinding getViewBinding(LayoutInflater inflater, ViewGroup container) {
return FragmentPictureBinding.inflate(LayoutInflater.from(getContext()));
}
#Override
public void onReceivedEvent(RxBusType type, Object data) {
switch (type) {
case SCREEN_SHOT:
case NOTI_MEDIA_CHANGE:
getData();
break;
}
}
}
I added popup menu on picture_item of recycle view and when we press delete button of popup menu I send String path of that image to deletePhoto(item); and that method delete image.
after delete image we have to manually refresh fragment by pull refresh But can add any automatic method for refreshing fragment In this case?
Please see deletePhoto method where I deleted photo but when
I tried refresh with removepos method its crash
I tried also many methods from stackoverflow but did not worked on my case
Please help me
You have already done everything uncomment your removeItem method and add pictureAdapter.notifyDataSetChanged() at the end of removeItem method
This will reload the data set of your adapter
If you know the position of the deleted element you can use
pictureAdapter.notifyItemRemoved(position)
This will tell your adapter you remove an item from the data set on a specific position
I am trying to do a simple widget for my app, which displays data from an API on the widget using ListView, but the list is empty even tho Logs says that the data was downloaded successfully.
Blank listView is displayed with no data in it. No errors are shown. What's the cause of it?
Resources I used when tried to solve this problem:
official documentation - https://developer.android.com/guide/topics/appwidgets#collections
similar question - How to use listview in a widget?
my AppWidgetProvider
public class Widget extends AppWidgetProvider {
RemoteViews views;
void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
views = new RemoteViews(context.getPackageName(), R.layout.my_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.my_widget);
Intent intent = new Intent(context, WidgetService.class);
remoteViews.setRemoteAdapter(R.id.appwidget_list_view, intent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
WidgetFactory and WidgetService
public class WidgetFactory implements RemoteViewsService.RemoteViewsFactory{
final Context context;
List<SimpleCoin> list;
List<Coin> coinList;
public WidgetFactory(Context context, Intent intent) {
this.context = context;
}
#Override
public void onCreate() {
//get data from database
CoinDatabase coinDatabase = CoinDatabase.buildDatabase(context);
list = coinDatabase.coinDao().getAllSimpleCoinsNonLive();
coinList = new ArrayList<>();
}
#Override
public void onDataSetChanged() {
//based on data from database download content (JSON)
if(list != null) {
Log.d("Widget", "Coin size -> " + list.size());
StringBuilder id = new StringBuilder("id=" + list.get(0).getId());
for (int j = 0; j < list.size(); j++) {
id.append(",");
id.append(list.get(j).getId());
}
String finalUrl = URL + id.toString() + API_KEY;
Observable.fromCallable(() -> {
HttpURLConnection connection = null;
BufferedReader reader = null;
java.net.URL url1 = new URL(finalUrl);
connection = (HttpURLConnection) url1.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder buffer = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
connection.disconnect();
reader.close();
return buffer.toString();
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
#Override
public void onSubscribe(#NonNull Disposable d) {
}
#Override
public void onNext(#NonNull String s) {
if (s != null) {
try {
//Create new coin and update list of coins
JSONObject object = new JSONObject(s);
for (int i = 0; i < list.size(); i++) {
JSONObject jsonObject = object.getJSONObject("data").getJSONObject(String.valueOf(list.get(i).getId()));
Log.d("Widget", "Coin -> " + jsonObject.getString("name") + jsonObject.getJSONObject("quote").getJSONObject("USD").getDouble("price") + jsonObject.getJSONObject("quote").getJSONObject("USD").getDouble("percent_change_7d"));
Coin coin = new Coin(jsonObject.getString("name"), jsonObject.getJSONObject("quote").getJSONObject("USD").getDouble("price"), jsonObject.getJSONObject("quote").getJSONObject("USD").getDouble("percent_change_7d"), false);
coinList.add(coin);
getViewAt(i);
}
} catch (JSONException e) {
Log.d("Widget", "Coin -> " + e.toString());
e.printStackTrace();
}
}
}
#Override
public void onError(#NonNull Throwable e) {
}
#Override
public void onComplete() {
}
});
}
}
#Override
public void onDestroy() {}
#Override
public int getCount() {
return list.size();
}
#Override
public RemoteViews getViewAt(int i) {
//Set ListData based on coinList
Log.d("Widget", "Coin size getViewAt -> " + list.size() + "item num ->" + i);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.my_widget_list_item);
if(coinList != null)
if(coinList.size() > i) {
Log.d("Widget", "Coin position added" + coinList.get(i).getName());
remoteViews.setTextViewText(R.id.widgetItemTaskNameLabel, coinList.get(i).getName());
}
return remoteViews;
}
#Override
public RemoteViews getLoadingView() {
return null;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public boolean hasStableIds() {
return true;
}
}
public class WidgetService extends RemoteViewsService {
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new WidgetFactory(this.getApplicationContext(), intent);
}
}
Here are my logs:
D/Widget: Coin size getViewAt -> 1 item num ->0
D/Widget: Coin size getViewAt -> 1 item num ->0
D/Widget: Coin -> testCoin0.00.0
D/Widget: Coin size getViewAt -> 1 item num ->0
D/Widget: Coin position added testCoin
my_widget.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/colorPrimary"
android:padding="#dimen/widget_margin">
<TextView
android:id="#+id/appwidget_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:background="#color/colorPrimary"
android:contentDescription="#string/appwidget_text"
android:text="#string/appwidget_text"
android:textColor="#ffffff"
android:textSize="24sp"
android:textStyle="bold|italic" />
<ListView
android:id="#+id/appwidget_list_view"
android:layout_width="match_parent"
android:layout_margin="8dp"
tools:listitem="#layout/my_widget_list_item"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:layout_below="#id/appwidget_text">
</ListView>
</RelativeLayout>
my_widget_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:paddingLeft="#dimen/widget_listview_padding_x"
android:paddingRight="#dimen/widget_listview_padding_x"
android:paddingStart="#dimen/widget_listview_padding_x"
android:paddingEnd="#dimen/widget_listview_padding_x"
android:minHeight="#dimen/widget_listview_item_height"
android:weightSum="2"
android:layout_height="wrap_content">
<TextView
android:id="#+id/widgetItemTaskNameLabel"
android:layout_width="0dp"
android:gravity="start"
android:layout_weight="1"
android:textColor="#color/colorPrimary"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content" />
</LinearLayout>
I found my mistake, turns out my API call shouldn't be asynchronous because as the documentation says:
public void onDataSetChanged() ->
You can do heaving lifting in here, synchronously. For example, if you need to process an image, fetch something from the network, etc., it is ok to do it here, synchronously. The widget will remain in its current state while work is being done here, so you don't need to worry about locking up the widget.
So getting my data from Asynchronous call was the reason why data wasn't displayed
I am getting tired fixing this problem. the app does not execute it always show me this error Binary XML file line #26: Error inflating class EditText. I don't understand how to fix this problem.
This is my activity_members.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.constraint.ConstraintLayout
android:id="#+id/newMeetScreen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
tools:layout_editor_absoluteX="384dp">
<ImageView
android:id="#+id/imageView3"
android:layout_width="0dp"
android:layout_height="54dp"
android:src="#drawable/gradient"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/edit_search"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="11dp"
android:layout_marginTop="7dp"
android:layout_marginEnd="13dp"
android:layout_marginBottom="7dp"
android:background="#drawable/radius_edit_text"
android:drawableLeft="#drawable/ic_search"
android:drawablePadding="3dp"
android:hint="Поиск"
android:imeOptions="actionGo"
android:inputType="text"
android:textColor="#color/colorPrimaryDark"
android:textColorHint="#9b9a9a"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/btnDone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/btnDone"
android:layout_width="52dp"
android:layout_height="50dp"
android:background="#android:drawable/list_selector_background"
android:src="#drawable/ic_done"
android:textColor="#color/colorProjectTextWhite"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/edit_search"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<android.support.v7.widget.RecyclerView
android:background="#color/colorBackgroundLight"
android:id="#+id/membersList"
android:scrollbars="vertical"
android:layout_marginTop="0dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
And this is my MembersActivity.java class.
public class MembersActivity extends AppCompatActivity {
private static final int REQUEST_CODE_READ_CONTACTS = 1;
private static boolean READ_CONTACTS_GRANTED = false;
RecyclerView members;
ArrayList<String> contacts = new ArrayList<String>();
ArrayList<String> tell = new ArrayList<String>();
UserAdapter adapter;
User user;
ArrayList<User> users = new ArrayList<>();
ImageButton btnDone;
StringBuilder stringBuilder = null;
EditText editSearch;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_members);
members = findViewById(R.id.membersList);
btnDone = findViewById(R.id.btnDone);
editSearch = findViewById(R.id.edit_search);
int hasReadContactPermission = ContextCompat.checkSelfPermission(Objects.requireNonNull(this), Manifest.permission.READ_CONTACTS);
if (hasReadContactPermission == PackageManager.PERMISSION_GRANTED) {
READ_CONTACTS_GRANTED = true;
} else {
ActivityCompat.requestPermissions(Objects.requireNonNull(this), new
String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CODE_READ_CONTACTS);
}
if (READ_CONTACTS_GRANTED) {
getContacts();
}
btnDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
stringBuilder = new StringBuilder();
int i=0;
char ch = ',';
do{
User user = adapter.checkedUsers.get(i);
if(i == adapter.checkedUsers.size()-1) ch = '.';
stringBuilder.append(user.getName() + ch);
if(i != adapter.checkedUsers.size() -1) {
stringBuilder.append("\n");
}
i++;
} while (i < adapter.checkedUsers.size());
if(adapter.checkedUsers.size() > 0) {
Intent intent = new Intent();
intent.putExtra("names", stringBuilder.toString());
setResult(RESULT_OK, intent);
finish();
} else {
Toast.makeText(MembersActivity.this, "Пожалуйста, выберите друзей", Toast.LENGTH_LONG).show();
}
}
});
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
adapter.getFilter().filter(charSequence);
return;
}
#Override
public void afterTextChanged(Editable editable) {
}
});
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_READ_CONTACTS:
if (grantResults.length > 0 && grantResults[0] ==
PackageManager.PERMISSION_GRANTED) {
READ_CONTACTS_GRANTED = true;
}
}
if (READ_CONTACTS_GRANTED) {
getContacts();
}
else {
Toast.makeText(this, "Требуется установить разрешения", Toast.LENGTH_LONG).show();
}
}
public void getContacts() {
Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;
String _ID = ContactsContract.Contacts._ID;
String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;
String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;
Uri PhoneCONTENT_URI =
ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
String Phone_CONTACT_ID =
ContactsContract.CommonDataKinds.Phone.CONTACT_ID;
String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;
StringBuffer output = new StringBuffer();
ContentResolver contentResolver = Objects.requireNonNull(this).getContentResolver();
Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String contact_id = cursor.getString(cursor.getColumnIndex(_ID));
String name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER)));
if (hasPhoneNumber > 0) {
contacts.add(name);
Cursor phoneCursor =
contentResolver.query(PhoneCONTENT_URI, null,
Phone_CONTACT_ID + " = ?", new String[]{contact_id}, null);
while (phoneCursor.moveToNext()) {
String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));
tell.add(phoneNumber);
}
}
}
}
if(tell.size() > contacts.size()) {
for(int i=0; i <contacts.size(); i++) {
user = new User(tell.get(i), contacts.get(i));
users.add(user);
}
} else {
for(int i=0; i < tell.size(); i++) {
user = new User(tell.get(i), contacts.get(i));
users.add(user);
}
}
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
adapter = new UserAdapter(users, this);
members.setLayoutManager(mLayoutManager);
members.setItemAnimator(new DefaultItemAnimator());
members.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
members.setAdapter(adapter);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
Please, help me fix this problem.
You need to set the width and height of your EditText in your layout file you cannot set these properties to 0dp. If you want to set this according to screen size then you can use layout_weight in your xml.Here you can know about layout_weight usage
If you are using constraintLayout in your layout you can see this link. Responsive layout designing with constraint layout
I am working on android application and I am facing one problem. When I run my app then nothing showing in recycle view but when i check application in debug mode then data successfully showing in recycle view. I have checked my web service working fine and successfully giving data. How can i achieve this ?
ManageQuestionActivity,java
public class ManageQuestionActivity extends AppCompatActivity implements RecyclerView.OnScrollChangeListener{
private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView listView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
private QuestionsListAdapter listAdapter;
private List<QuestionsItem> timeLineItems;
private int requestCount = 1;
private ProgressDialog pDialog;
public static String id, message, token, encodedString;
int pageCount, totalPages;
SQLiteHandler db;
SessionManager session;
ConnectionDetector cd;
EditText edtSearch;
Boolean isInternetPresent = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_manage_question);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
listView = (RecyclerView) findViewById(R.id.list);
edtSearch = (EditText) findViewById(R.id.edtSearch);
listView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
//Adding an scroll change listener to recyclerview
listView.setOnScrollChangeListener(this);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
cd = new ConnectionDetector(this);
isInternetPresent = cd.isConnectingToInternet();
db = new SQLiteHandler(this);
// session manager
session = new SessionManager(this);
// Fetching user details from sqlite
HashMap<String, String> user = db.getUserDetails();
id = user.get("id");
token = user.get("token");
getData();
timeLineItems = new ArrayList<>();
adapter = new QuestionsListAdapter(timeLineItems, this);
listView.setAdapter(adapter);
}
public void getTimeLineData(final String token, final String page) {
String tag_string_req = "req_register";
// making fresh volley request and getting json
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.questions, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.d(TAG, "Response: " + response.toString());
if (response != null) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("status");
String message = jObj.getString("message");
if (error) {
totalPages = jObj.getInt("totalPages");
pageCount = jObj.getInt("page");
int limit = jObj.getInt("limit");
parseJsonFeed(response);
}
} catch (Exception e) {
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("my_token", token);
params.put("page", page);
params.put("limit", "20");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void parseJsonFeed(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray feedArray = jsonObj.getJSONArray("data");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
QuestionsItem item = new QuestionsItem();
item.setId(feedObj.getInt("id"));
item.setQuestion(feedObj.getString("question"));
String options = feedObj.getString("multi_ans_option");
String[] parts = options.split("\\|");
String part1 = parts[0];
String part2 = parts[1];
String part3 = parts[2];
String part4 = parts[3];
item.setAnsOne(part1);
item.setAnsTwo(part2);
item.setAnsThree(part3);
item.setAnsFour(part4);
item.setAnswer(feedObj.getString("answer"));
timeLineItems.add(item);
}
// notify data changes to list adapater
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
getTimeLineData(token, String.valueOf(requestCount));
//Incrementing the request counter
requestCount++;
}
//This method would check that the recyclerview scroll has reached the bottom or not
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//Ifscrolled at last then
if (isLastItemDisplaying(listView)) {
//Calling the method getdata again
getData();
}
}
}
activity_manage_question.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#null" />
</LinearLayout>
QuestionsItem.java
public class QuestionsItem {
private int id;
private String question, ansOne, ansTwo, ansThree, ansFour, answer;
public QuestionsItem() {
}
public QuestionsItem(int id, String question, String ansOne, String ansTwo, String ansThree, String ansFour, String answer) {
super();
this.id = id;
this.question = question;
this.ansOne = ansOne;
this.ansTwo = ansTwo;
this.ansThree = ansThree;
this.ansFour = ansFour;
this.answer = answer;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getAnsOne() {
return ansOne;
}
public void setAnsOne(String ansOne) {
this.ansOne = ansOne;
}
public String getAnsTwo() {
return ansTwo;
}
public void setAnsTwo(String ansTwo) {
this.ansTwo = ansTwo;
}
public String getAnsThree() {
return ansThree;
}
public void setAnsThree(String ansThree) {
this.ansThree = ansThree;
}
public String getAnsFour() {
return ansFour;
}
public void setAnsFour(String ansFour) {
this.ansFour = ansFour;
}
public String getAnswer() {
return answer;
}
public void setAnswer(String answer) {
this.answer = answer;
}
}
QuestionsListAdapter.java
public class QuestionsListAdapter extends RecyclerView.Adapter<QuestionsListAdapter.ViewHolder> {
private List<QuestionsItem> timeLineItems;
String message, storyId, token, ide;
private Context context;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
ConnectionDetector cd;
Boolean isInternetPresent = false;
private ProgressDialog pDialog;
private SessionManager session;
private SQLiteHandler db;
int newPosition;
public QuestionsListAdapter(List<QuestionsItem> timeLineItems, Context context) {
super();
this.context = context;
this.timeLineItems = timeLineItems;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.questios_item, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
pDialog = new ProgressDialog(context);
pDialog.setCancelable(false);
db = new SQLiteHandler(context);
// session manager
session = new SessionManager(context);
// Fetching user details from sqlite
HashMap<String, String> user = db.getUserDetails();
token = user.get("token");
//Getting the particular item from the list
QuestionsItem item = timeLineItems.get(position);
holder.txtQues.setText(item.getQuestion());
holder.txtAnsOne.setText(item.getAnsOne());
holder.txtAnsTwo.setText(item.getAnsTwo());
holder.txtAnsThree.setText(item.getAnsThree());
holder.txtAnsFour.setText(item.getAnsFour());
holder.txtAns.setText(item.getAnswer());
holder.btnEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final QuestionsItem m = timeLineItems.get(position);
String ide = String.valueOf(m.getId());
String ques = String.valueOf(m.getQuestion());
String Option1 = String.valueOf(m.getAnsOne());
String Option2 = String.valueOf(m.getAnsTwo());
String Option3 = String.valueOf(m.getAnsThree());
String Option4 = String.valueOf(m.getAnsFour());
String answer = String.valueOf(m.getAnswer());
Intent intent = new Intent(context, UpdateQuestionActivity.class);
intent.putExtra("id", ide);
intent.putExtra("ques", ques);
intent.putExtra("option1", Option1);
intent.putExtra("option2", Option2);
intent.putExtra("option3", Option3);
intent.putExtra("option4", Option4);
intent.putExtra("answer", answer);
context.startActivity(intent);
}
});
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final QuestionsItem m = timeLineItems.get(position);
newPosition = holder.getAdapterPosition();
ide = String.valueOf(m.getId());
alertBox();
}
});
}
#Override
public int getItemCount() {
return timeLineItems.size();
}
#Override
public int getItemViewType(int position)
{
return position;
}
class ViewHolder extends RecyclerView.ViewHolder{
TextView txtQues, txtAnsOne, txtAnsTwo, txtAnsThree, txtAnsFour, txtAns, btnEdit, btnDelete;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
txtQues = (TextView) itemView.findViewById(R.id.txtQues);
txtAnsOne = (TextView) itemView.findViewById(R.id.txtAnsOne);
txtAnsTwo = (TextView) itemView.findViewById(R.id.txtAnsTwo);
txtAnsThree = (TextView) itemView.findViewById(R.id.txtAnsThree);
txtAnsFour = (TextView) itemView.findViewById(R.id.txtAnsFour);
txtAns = (TextView) itemView.findViewById(R.id.txtAns);
btnEdit = (TextView) itemView.findViewById(R.id.btnEdit);
btnDelete = (TextView) itemView.findViewById(R.id.btnDelete);
}
}
public void alertBox(){
AlertDialog.Builder builder = new AlertDialog.Builder(context);
//Uncomment the below code to Set the message and title from the strings.xml file
//builder.setMessage(R.string.dialog_message) .setTitle(R.string.dialog_title);
//Setting message manually and performing action on button click
builder.setMessage("Do you want to delete question ?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Check for empty data in the form
cd = new ConnectionDetector(context);
isInternetPresent = cd.isConnectingToInternet();
if (isInternetPresent){
DeleteQuestion(token, ide);
}else {
final SweetAlertDialog alert = new SweetAlertDialog(context, SweetAlertDialog.WARNING_TYPE);
alert.setTitleText("No Internet");
alert.setContentText("No connectivity. Please check your internet.");
alert.show();
}
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Action for 'NO' Button
dialog.cancel();
}
});
//Creating dialog box
AlertDialog alert = builder.create();
//Setting the title manually
alert.setTitle("Question");
alert.show();
}
private void DeleteQuestion(final String token, final String qid) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Please wait ...");
showDialog();
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.updateQues, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("status");
if (error) {
String errorMsg = jObj.getString("message");
Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show();
timeLineItems.remove(newPosition);
notifyItemRemoved(newPosition);
notifyItemRangeChanged(newPosition, timeLineItems.size());
} else {
// Error occurred in registration. Get the error
// message
String errorMsg = jObj.getString("message");
Toast.makeText(context, errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, "Oops something went wrong...", Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("my_token", token);
params.put("qid", qid);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
questios_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp"
android:background="#color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Question : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtQues"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1 : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtAnsOne"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2 : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtAnsTwo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 3 : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtAnsThree"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 4 : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtAnsFour"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Answer : "
android:textColor="#000000"
android:textSize="15sp" />
<TextView
android:id="#+id/txtAns"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<TextView android:id="#+id/btnEdit"
android:layout_width="0dp"
android:layout_height="30dp"
android:text="Edit"
android:background="#drawable/rounded_square_comment"
android:gravity="center"
android:textColor="#000000"
android:layout_weight="1"
android:textSize="15sp" />
<TextView
android:id="#+id/btnDelete"
android:layout_width="0dp"
android:layout_height="30dp"
android:text="Delete"
android:background="#drawable/rounded_square_comment"
android:gravity="center"
android:textColor="#000000"
android:layout_weight="1"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
listView.setAdapter should not be here cut
timeLineItems = new ArrayList<>();
adapter = new QuestionsListAdapter(timeLineItems, this);
listView.setAdapter(adapter); // Cut from Here
And paste in this method:
private void parseJsonFeed(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray feedArray = jsonObj.getJSONArray("data");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
QuestionsItem item = new QuestionsItem();
item.setId(feedObj.getInt("id"));
item.setQuestion(feedObj.getString("question"));
String options = feedObj.getString("multi_ans_option");
String[] parts = options.split("\\|");
String part1 = parts[0];
String part2 = parts[1];
String part3 = parts[2];
String part4 = parts[3];
item.setAnsOne(part1);
item.setAnsTwo(part2);
item.setAnsThree(part3);
item.setAnsFour(part4);
item.setAnswer(feedObj.getString("answer"));
timeLineItems.add(item);
listView.setAdapter(adapter); //Paste Here
}
// notify data changes to list adapater
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
I have a gridview with 5 columns, how could add in column 4 and 5, images that I have in drawable folder? The problem is that being a String arraylist not catch me drawable because it is an integer.
This is my XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrolView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical">
<GridView
android:id="#+id/Grid"
android:numColumns="5"
android:stretchMode="columnWidth"
android:layout_width="match_parent"
android:gravity="center"
android:columnWidth="120dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:layout_height="2000dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"></GridView>
</LinearLayout>
This is the java code where I call carrito.xml, and i make the listview. This list view is filled with a String array.
public class carrito extends Fragment {
protected Context context;
private int numComandesCarrito;
private String[][] CarritoProductes;
private double Total;
DecimalFormat precision = new DecimalFormat("0.00");
NumberFormat formatter = NumberFormat.getCurrencyInstance();
String output = formatter.format(Total);
public carrito(){
}
public void setContext (Context context){
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int i, i2;
numComandesCarrito = ((MainActivity) context).getNumComandesCarrito();
// Toast.makeText(context, Integer.toString(numComandesCarrito), Toast.LENGTH_LONG).show();
CarritoProductes = ((MainActivity) context).getCarritoProductes();
Total = 0;
ArrayList<String> lineasPedido = new ArrayList<String>();
ArrayList<Integer> itemsimg = new ArrayList( );
//Afegim la capçalera de la grid
lineasPedido.add("Plat");
lineasPedido.add("Quantitat");
lineasPedido.add("Preu");
for (i= 0; i < numComandesCarrito; i++){
for (i2 = 0; i2<3; i2++){
if (i2 == 2) {
lineasPedido.add(precision.format(Double.parseDouble(CarritoProductes[i2][i])) + " €");
Total = Total + Double.parseDouble(CarritoProductes[i2][i]);
}
else{
lineasPedido.add(CarritoProductes[i2][i]);
}
}
itemsimg.add(R.drawable.botonmenos);
}
lineasPedido.add("");
lineasPedido.add("");
lineasPedido.add("Total: " + (precision.format(Total)) + " €");
View rootView = inflater.inflate(R.layout.carrito, container, false);
GridView grdView = (GridView)rootView.findViewById(R.id.grdComanda);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getActivity(), android.R.layout.simple_list_item_1, lineasPedido);
grdView.setAdapter(adapter);
return rootView;
}
You have to use custom adapter to put image in gridview
activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<GridView
android:id="#+id/gridView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:horizontalSpacing="5dp"
android:numColumns="2"
android:verticalSpacing="5dp" >
</GridView>
</RelativeLayout>
row.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutbg"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="250dp"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:id="#+id/img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/ic_launcher" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:paddingLeft="15dp"
android:text="TextView" />
<TextView
android:id="#+id/num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:paddingRight="15dp"
android:text="TextView" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
FriendAdapter.java
public class FriendAdapter extends ArrayAdapter<FriendBean>{
private Context mCtx;
private ArrayList<FriendBean> items = new ArrayList<FriendBean>();
private ViewHolder mHolder;
ImageLoader imgLoader = new ImageLoader(mCtx);
public LayoutInflater inflater;
int loader = R.drawable.loader;
public FriendAdapter(Context context, int textViewResourceId, ArrayList<FriendBean> items) {
super(context, textViewResourceId, items);
this.items = items;
this.mCtx = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) mCtx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v=vi.inflate(R.layout.row, null);
mHolder=new ViewHolder();
mHolder.mImage=(ImageView)v.findViewById(R.id.img);
mHolder.mName=(TextView)v.findViewById(R.id.name);
mHolder.mPh=(TextView)v.findViewById(R.id.num);
mHolder.mlayoutbg=(RelativeLayout)v.findViewById(R.id.layoutbg);
v.setTag(mHolder);
}
else{
mHolder=(ViewHolder)v.getTag();
}
imgLoader.DisplayImage(items.get(position).getImage(), loader, mHolder.mImage);
//mHolder.mImage.setBackgroundResource(items.get(position).getImage());
mHolder.mName.setText(items.get(position).getName());
mHolder.mPh.setText(items.get(position).getPh());
mHolder.mlayoutbg.setBackgroundColor(Color.GREEN);
// if(position%3==1){
// mHolder.mlayoutbg.setBackgroundColor(Color.GRAY);
// }else if(position%3==2){
// mHolder.mlayoutbg.setBackgroundColor(Color.WHITE);
// }else{
// mHolder.mlayoutbg.setBackgroundColor(Color.YELLOW);
// }
return v;
}
public class ViewHolder {
public ImageView mImage;
public TextView mName;
public TextView mPh;
public RelativeLayout mlayoutbg;
}
}
FriendBean.java
package com.example.bean;
public class FriendBean {
private String Image;
private String name;
private String ph;
private String des;
public FriendBean(String Image, String name, String ph, String des) {
this.Image = Image;
this.name = name;
this.ph = ph;
this.des = des;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPh() {
return ph;
}
public void setPh(String ph) {
this.ph = ph;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
}
MainActivity.java
public class MainActivity extends Activity {
private GridView mList;
private ArrayList<FriendBean> arr = new ArrayList<FriendBean>();
private FriendAdapter friendAdapter;
String friend_name, friend_phone, url, des;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mList = (GridView) findViewById(R.id.gridView1);
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(
"gridarray.json")));
String temp;
while ((temp = br.readLine()) != null)
sb.append(temp);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException e) {
e.printStackTrace();
}
}
String myjsonstring = sb.toString();
try {
JSONObject obj = new JSONObject(myjsonstring);
JSONArray jsonarray = obj.getJSONArray("json");
Log.e("Length", "" + jsonarray.length());
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonObj = jsonarray.getJSONObject(i);
friend_name = jsonObj.getString("friend_name");
friend_phone = jsonObj.getString("friend_phone");
url = jsonObj.getString("image_url");
des = jsonObj.getString("des");
FriendBean bean = new FriendBean(url, friend_name, friend_phone,
des);
arr.add(bean);
Log.e("u", url);
Log.e("friend_name", friend_name);
Log.e("friend_phone", friend_phone);
}
friendAdapter = new FriendAdapter(MainActivity.this, R.layout.row, arr);
mList.setAdapter(friendAdapter);
mList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Clicked on " + arg2,
Toast.LENGTH_SHORT).show();
Intent i = new Intent(getApplicationContext(), NewPage.class);
i.putExtra("friend_name", arr.get(arg2).getName());
i.putExtra("friend_phone", arr.get(arg2).getPh());
i.putExtra("url", arr.get(arg2).getImage());
i.putExtra("des", arr.get(arg2).getDes());
startActivity(i);
}
});
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
gridarray.json (put it in asset folder)
{ "json" : [ { "image_url" : "http://www.ogmaconceptions.com/demo/NewsFeed/app_images/twitter_main.png",
"friend_name" : "Madhumoy",
"friend_phone" : "123",
"des" : "Hi I'm Madhumoy"
},
{ "image_url" : "http://www.ogmaconceptions.com/demo/NewsFeed/app_images/twitter_main.png",
"friend_name" : "Sattik",
"friend_phone" : "123",
"des" : "Hi I'm Sattik"
},
{ "image_url" : "http://www.ogmaconceptions.com/demo/NewsFeed/app_images/twitter_main.png",
"friend_name" : "Koushik",
"friend_phone" : "123",
"des" : "Hi I'm Koushik"
},
{ "image_url" : "http://www.ogmaconceptions.com/demo/NewsFeed/app_images/twitter_main.png",
"friend_name" : "Himanshu",
"friend_phone" : "123",
"des" : "Hi I'm Himanshu"
},
{ "image_url" : "http://www.ogmaconceptions.com/demo/NewsFeed/app_images/twitter_main.png",
"friend_name" : "Sandy",
"friend_phone" : "123",
"des" : "Hi I'm Sandy"
}
] }
Hope this will work..
Maybe try something like this? The user comments seem to be positive for the most part. http://www.compiletimeerror.com/2013/02/display-images-in-gridview.html#.VRF2I2NTf5w