Custom Card View Adapter : notify data set changed not working - java

Im setting up a custom card-view slider adapter and on startup the card view loads up fine but after items is added/replaced in the array list and the notify adapter method is called, no changes occur to the content.
I have already tried adding the items directly from the adapter via a public method and the item gets added however, it is always placed at the last position.
This is my adapter :
static class UploadImageAdapter extends CardSliderAdapter<ImageObject>
{
private Context context;
private ArrayList<ImageObject> arrayList;
private OnUploadButtonClick onUploadButtonClick;
public interface OnUploadButtonClick{
void upload(int position);
}
UploadImageAdapter(Context context, ArrayList<ImageObject> items) {
super(items);
this.context = context;
this.arrayList = items;
}
static class ViewHolder{
ImageView image;
ImageButton addImage;
Button removeImage;
View layout;
}
#Override
public void bindView(int position, #NotNull View itemContentView, ImageObject imageObject) {
final ViewHolder holder = new ViewHolder();
holder.image = itemContentView.findViewById(R.id.card_image);
holder.addImage = itemContentView.findViewById(R.id.upload_image_btn);
holder.removeImage = itemContentView.findViewById(R.id.card_remove_btn);
holder.layout = itemContentView.findViewById(R.id.card_image_layout);
if (imageObject.hasImage) {
Glide.with(context)
.load(Uri.parse(imageObject.getImage_path()))
.placeholder(R.color.offsetWhiteBackground)
.centerCrop()
.transition(withCrossFade())
.into(holder.image);
holder.addImage.setVisibility(View.GONE);
holder.layout.setVisibility(View.VISIBLE);
holder.removeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
else {
holder.layout.setVisibility(View.GONE);
holder.addImage.setVisibility(View.VISIBLE);
holder.addImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onUploadButtonClick.upload(position);
}
});
}
}
#Override
public ImageObject getItem(int position) {
return arrayList.get(position);
}
void setOnUploadButtonClick(OnUploadButtonClick onUploadButtonClick){
this.onUploadButtonClick = onUploadButtonClick;
}
#Override
public int getItemContentLayout(int position) {
//TODO return the item layout of every position
return R.layout.upload_image_card;
}
}
And below is where i instantiate :
private void setCardSlider() {
upload = new ArrayList<>();
for(int i = 0; i < 3; i++){
upload.add(new ImageObject(i,false,""));
}
adapter = new UploadImageAdapter(getContext(), upload);
CardSliderViewPager cardSliderViewPager = rootView.findViewById(R.id.image_upload_slider);
cardSliderViewPager.setAdapter(adapter);
uploadDialog = new UploadDialog(getActivity(), getContext());
adapter.setOnUploadButtonClick((int position) -> {
uploadDialog.callUploadDialog();
mPosition = position;
});
}
public void uploadImage(){
uploadDialog.callUploadDialog();
}
public void setImage(Uri uri){
upload.get(mPosition).setHasImage(true);
upload.get(mPosition).setImage_path(uri.toString());
adapter.notifyDataSetChanged();
}

I would suggest using notifyItemChange instead. There you use a position as a parameter and it doesn't need to redraw everything.

Related

Transition between 2 recycler views having cards

I have 2 recycler views that have cards.They basically look the same have the same number of cards and everthing. The first one is for like viewing and other stuff and the second one is only for deleting cards. OnlongClicking a card in the first recycler view triggers the opening of the second recycler view. I wanted to add transitions in between them like what keep notes has done when a card is long clicked. Both the recycler view use the same adapter. I have set what the adapter should do based on passing context to the adapter. enter image description here this is my 1st layout having the 1st recycler view.enter image description here this is the 2nd layout having the second recycler view.I want like a seamless transition for the tool bar again just like what Google keeps has done.A simple solution would be preferred as I am very new to this stuff.
Here is the java code for the adapter.
public class Task_recycle_view_adapter extends RecyclerView.Adapter<Task_recycle_view_adapter.ViewHolder>{
private List<struct_task> task_list= new ArrayList<>();
private ArrayList<String> isSelected=new ArrayList<String>();
protected Context context1;
protected Context context2;
private String labelName;
private String taskName;
private ConstraintLayout label_menu_avatar;
public Task_recycle_view_adapter(Context context1,Context context2)
{
this.context1=context1;
this.context2=context2;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {//parent is the parent of the recycle view it is taken as an arg to use it to attach the every view to the parent view
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_task,parent,false);//to inflate a layout
ViewHolder holder= new ViewHolder(view);
return holder;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.taskname.setText(task_list.get(position).getTask_name());
holder.taskid.setText(String.valueOf(task_list.get(position).getTask_id()));
if(context2==null && context1!=null) {
String taskName=task_list.get(position).getTask_name();
Long taskid=task_list.get(position).getTask_id();
String duedate=task_list.get(position).getDue_date();
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DataBaseHelper dataBaseHelper = new DataBaseHelper(context1);
ArrayList<SubTaskModel> subtask_list=(ArrayList<SubTaskModel>) dataBaseHelper.getAllSubTasksFor(labelName, Long.parseLong(holder.taskid.getText().toString()));
Intent intent1 =new Intent(context1,ViewTaskActivity.class);
intent1.putExtra("label_name",labelName);
intent1.putExtra("task_id",taskid);
intent1.putExtra("task_name",taskName);
intent1.putExtra("due_date",duedate);
intent1.putParcelableArrayListExtra("subtask_list", (ArrayList<? extends Parcelable>) subtask_list);
context1.startActivity(intent1);
}
});
holder.parent.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Intent intent2 = new Intent(context1, Delete_page_Activity.class);
intent2.putParcelableArrayListExtra("task_list", (ArrayList<? extends Parcelable>) task_list);
intent2.putExtra("label_name",labelName);
intent2.putExtra("selected_task",taskName);
Pair[] pairs = new Pair[1];
pairs[0]= new Pair<View,String>(label_menu_avatar,"transition1");
ActivityOptions options= ActivityOptions.makeSceneTransitionAnimation((Activity) context1,pairs);
context1.startActivity(intent2,options.toBundle());
return true;
}
});
}
if(context2!=null && context1==null)
{
if(taskName.equals(task_list.get(position).getTask_name()))
{
holder.active=1;
isSelected.add(holder.taskid.getText().toString());
holder.parent.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
}
holder.parent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.active==0) {
isSelected.add(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card);
holder.active=1;
}
else {
isSelected.remove(holder.taskid.getText().toString());
v.findViewById(R.id.layout_for_every_task).setBackgroundResource(R.drawable.background_for_task_card_transparent);
holder.active=0;
}
}
});
}
// subtasks 1 to 5
if(task_list.get(position).getSubtask1()!=null)
holder.subtask1.setText(task_list.get(position).getSubtask1());
else
holder.subtask1.setVisibility(View.GONE);
if(task_list.get(position).getSubtask2()!=null)
holder.subtask2.setText(task_list.get(position).getSubtask2());
else
holder.subtask2.setVisibility(View.GONE);
if(task_list.get(position).getSubtask3()!=null)
holder.subtask3.setText(task_list.get(position).getSubtask3());
else
holder.subtask3.setVisibility(View.GONE);
if(task_list.get(position).getSubtask4()!=null)
holder.subtask4.setText(task_list.get(position).getSubtask4());
else
holder.subtask4.setVisibility(View.GONE);
if(task_list.get(position).getSubtask5()!=null)
holder.subtask5.setText(task_list.get(position).getSubtask5());
else
holder.subtask5.setVisibility(View.GONE);
// due date
if(task_list.get(position).getDue_date()!=null)
holder.duedate.setText(task_list.get(position).getDue_date());
else
holder.duedate.setVisibility(View.GONE);
// progress
holder.progresscircle.setProgress(task_list.get(position).getProgress());
}
#Override
public int getItemCount() {
return task_list.size();
}
public void setTask_list(List<struct_task> task_list) {
this.task_list = task_list;//to refresh the data inside the recycler view
}
#Override
public int getItemViewType(int position) {
return position;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public ArrayList<String> getIsSelected() {
return isSelected;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public void setLabel_menu_avatar(ConstraintLayout label_menu_avatar) {
this.label_menu_avatar = label_menu_avatar;
}
public static class ViewHolder extends RecyclerView.ViewHolder{// holds the view for every item inside the recycle view
private TextView taskname,taskid,duedate,subtask1,subtask2,subtask3,subtask4,subtask5;
private CardView parent;
private ProgressBar progresscircle;
public void setActive(int active) {
this.active = active;
}
private int active;
public ViewHolder(#NonNull View itemView) {
super(itemView);
taskid=itemView.findViewById(R.id.task_id);
taskname = itemView.findViewById(R.id.task_name);
parent = itemView.findViewById(R.id.card_for_every_task);
duedate = itemView.findViewById(R.id.due_date);
progresscircle = itemView.findViewById(R.id.progress_circular);
subtask1 = itemView.findViewById(R.id.subtask_1);
subtask2 = itemView.findViewById(R.id.subtask_2);
subtask3 = itemView.findViewById(R.id.subtask_3);
subtask4 = itemView.findViewById(R.id.subtask_4);
subtask5 = itemView.findViewById(R.id.subtask_5);
active=0;
}
}
}
Here is the code for the 1st activity i.e the 1st image:
public class TaskPageActivity extends AppCompatActivity {
private RecyclerView task_rv;//task recycler view
private FloatingActionButton addTask;
private long tasksNum;
private String labelName;
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private Task_recycle_view_adapter adapter= new Task_recycle_view_adapter(this,null);
private List<struct_task> tasks;
private EditText searchBar;
private ConstraintLayout search_btn;
private ConstraintLayout calendar_btn;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_title);
getWindow().getSharedElementExitTransition();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
search_btn= findViewById(R.id.search_btn);
calendar_btn=findViewById(R.id.calendar_btn);
search_btn.setClickable(true);
search_btn.setFocusable(true);
labelName = getIntent().getExtras().getString("832715");
TextView txtLabelName = findViewById(R.id.Label_name);
txtLabelName.setText(labelName);
task_rv = findViewById(R.id.Recycle_view_task);
addTask = findViewById(R.id.add_task);
searchBar= (SearchBar) findViewById(R.id.search_bar);
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter); //displays all tasks and return number of tasks
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
addTask.setOnClickListener(view -> {
tasksNum = getTasksNum(labelName, dataBaseHelper, adapter);
Intent intent = new Intent(TaskPageActivity.this, AddTaskPageActivity.class);
intent.putExtra("labelName", labelName);
intent.putExtra("taskID", tasksNum);
startActivity(intent);
});
search_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(searchBar.getVisibility()==View.INVISIBLE) {
search_btn.setAlpha(.5f);
searchBar.setVisibility(View.VISIBLE);
searchBar.requestFocus();
imm.showSoftInput(searchBar,InputMethodManager.SHOW_IMPLICIT);
ConstraintLayout.LayoutParams params= (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
searchBar.requestFocus();
}
else {
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
}
});
searchBar.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
if(params.verticalBias==.9f) {
searchBar.requestFocus();
params.verticalBias = .55f;
searchBar.setLayoutParams(params);
}
searchBar.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if((event.getAction()==KeyEvent.ACTION_DOWN) && (keyCode==KeyEvent.KEYCODE_ENTER) && params.verticalBias==.55f)
{
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
imm.hideSoftInputFromWindow(searchBar.getWindowToken(),0);
}
return false;
}
});
}
}
});
searchBar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
AlertDialog alertDialog = new AlertDialog.Builder(TaskPageActivity.this).create();
calendar_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(calendar_btn.getAlpha()==1.0f) {
calendar_btn.setAlpha(.5f);
LayoutInflater inflater = getLayoutInflater();
View view1 = inflater.inflate(R.layout.dialog_calendar,null);
alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
alertDialog.setView(view1);
CalendarView mCalendarView= view1.findViewById(R.id.calendar);
mCalendarView.setMinDate(Calendar.getInstance().getTimeInMillis());
alertDialog.show();
}
}
});
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
if(calendar_btn.getAlpha()==.5f)
calendar_btn.setAlpha(1.0f);
}
});
}
private void filter(String string) {
ArrayList<struct_task> filteredList = new ArrayList<>();
for(struct_task item: tasks)
{
if(item.getTask_name().contains(string) || item.getTask_name().contains(string.toUpperCase()))
{
filteredList.add(item);
}
}
if(filteredList.size()!=0) {
adapter.setTask_list(filteredList);
task_rv.setAdapter(adapter);
}
}
#Override
public void onBackPressed() {
if(searchBar.getText().toString().length()!=0) {
showAllTasks(labelName, dataBaseHelper, adapter);
searchBar.setText(null);
searchBar.setVisibility(View.INVISIBLE);
search_btn.setAlpha(1.0f);
}
else if(searchBar.getText().toString().length()==0)
{
super.onBackPressed();
}
}
#Override
protected void onResume() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
showAllTasks(labelName, dataBaseHelper, adapter);
if(params.verticalBias==.54f) {
searchBar.requestFocus();
params.verticalBias = .9f;
searchBar.setLayoutParams(params);
searchBar.clearFocus();
}
if(searchBar.getText().toString().length()==0) {
showAllTasks(labelName, dataBaseHelper, adapter);
}
else {
filter(searchBar.getText().toString());
}
super.onResume();
}
private void showAllTasks(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
tasks = dataBaseHelper.getAllTasksFor(labelName);
adapter.setLabelName(labelName);
adapter.setTask_list(tasks);
task_rv.setAdapter(adapter);
task_rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
}
long getTasksNum(String labelName, DataBaseHelper dataBaseHelper, Task_recycle_view_adapter adapter) {
return dataBaseHelper.getLastTaskID(labelName)+1; //to determine ID of next task
}
#Override
protected void onUserLeaveHint() {
ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) searchBar.getLayoutParams();
params.verticalBias=.9f;
searchBar.setLayoutParams(params);
searchBar.setText(null);
searchBar.clearFocus();
super.onUserLeaveHint();
}
}
And finally for the 2nd activity which is triggered by longclicking any card
public class Delete_page_Activity extends AppCompatActivity {
private Task_recycle_view_adapter recycle_view_adapter = new Task_recycle_view_adapter(null,this);
private ArrayList<String> delete_list=new ArrayList<>();
private DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
private String labelName=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delete_page);
overridePendingTransition(0,0);
Toolbar toolbar=findViewById(R.id.toolbar_bar);
ImageView close_btn=findViewById(R.id.close_btn);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
ArrayList<struct_task> task_list = getIntent().getParcelableArrayListExtra("task_list");
labelName=getIntent().getExtras().getString("label_name");
String task = getIntent().getExtras().getString("selected_task");
Log.e("test",labelName);
RecyclerView recyclerView = findViewById(R.id.delete_Recycler_View);
recycle_view_adapter.setTaskName(task);
recycle_view_adapter.setTask_list(task_list);
recyclerView.setAdapter(recycle_view_adapter);
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
close_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId())
{
case R.id.tool_bar_item1:
delete_list = recycle_view_adapter.getIsSelected();
if(delete_list.size()==0)
{
Toast toast1= new Toast(this);
toast1.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg1,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast1.setView(view);
toast1.show();
}
else {
for (int task = 0; task < delete_list.size(); task++) {
dataBaseHelper.deleteOneTask(labelName, Long.parseLong(delete_list.get(task)));
}
finish();
}
break;
case R.id.tool_bar_item2:
Boolean flag=dataBaseHelper.deleteAllCompletedTasks(labelName);
if(flag)
finish();
else
{
Toast toast2= new Toast(this);
toast2.setDuration(Toast.LENGTH_SHORT);
LayoutInflater inflater= (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view= inflater.inflate(R.layout.activity_toast_msg2,null);
view.setBackgroundResource(R.drawable.background_for_calendar);
toast2.setView(view);
toast2.show();
}
break;
}
return true;
}
}
I have added the code related to the scene transititon which is in the adapter.
here is a gif of the problem when i add a scene transition
enter image description here
As u can see there are 2 pauses when going from 1st to 2nd activity 1st pause being longer 2nd one shorter. And also a pause when exiting the 2nd activity which seems to have the same duration as the 2nd pause.

How to load data into recyclerView

In my application i want get some data from server and show into recyclerView. For application architecture i used MVP
I wrote below codes, but after loaded data from server, not show any data into recyclerView!
I used debug mode and show me data in this break point
public void add(List<DataItem> list) {
list.addAll(list);
notifyDataSetChanged();
}
but not show me data into recyclerView!
My Activity codes :
public class ListFragment extends Fragment implements ActiveTestsContract.View {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tester_active_tests, container, false);
//Initialize
init();
//User token log
if (!App.isEmptyString(App.getPrefs("JWT")) || !App.getPrefs("JWT").equals(ConstKeys.EMPTY)) {
userToken = App.getPrefs("JWT");
}
//Load data
getData();
return view;
}
#Override
public void updateTestsList(Data data, int page) {
testerDashboard_emptyLay.setVisibility(View.GONE);
activeTests_pullToLoader.setVisibility(View.VISIBLE);
//Get lasted page
if (page == data.getLastPage()) {
isHasLoadedAll = true;
activeTests_pullToLoader.setComplete();
}
adapter.add(data.getData());
//Complete items
isLoading = false;
nextPage = page + 1;
activeTests_pullToLoader.setComplete();
}
#Override
public void init() {
context = getActivity();
handler = new Handler(Looper.getMainLooper());
testsPresenter = new ActiveTestsPresenter(this, 3);
testerDashboard_loader = view.findViewById(R.id.testerDashboard_loader);
activeTests_pullToLoader = view.findViewById(R.id.activeTests_pullToLoader);
testerDashboard_emptyLay = view.findViewById(R.id.testerDashboard_emptyLay);
emptyLayout_editProfileBtn = view.findViewById(R.id.emptyLayout_editProfileBtn);
layoutManager = new LinearLayoutManager(context);
recyclerView = activeTests_pullToLoader.getRecyclerView();
//Adapter
adapter = new TesterActiveRecyclerAdapter(activeModel, context);
//Init recycler and adapter
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
activeTests_pullToLoader.setColorSchemeResources(R.color.colorPrimary);
}
private void getData() {
activeTests_pullToLoader.isLoadMoreEnabled(true);
activeTests_pullToLoader.setPullCallback(new PullCallback() {
#Override
public void onLoadMore() {
isLoading = true;
//Call api
testsPresenter.testsListResponse(App.recipesApi, userToken, nextPage);
}
#Override
public void onRefresh() {
adapter.clear();
isHasLoadedAll = false;
isLoading = true;
//Call api
testsPresenter.testsListResponse(App.recipesApi, userToken, 1);
}
#Override
public boolean isLoading() {
return isLoading;
}
#Override
public boolean hasLoadedAllItems() {
return isHasLoadedAll;
}
});
activeTests_pullToLoader.initLoad();
}
Adapter codes:
public class TesterActiveRecyclerAdapter extends RecyclerView.Adapter<TesterActiveRecyclerAdapter.ViewHolder> {
private List<DataItem> list;
private Context context;
public TesterActiveRecyclerAdapter(List<DataItem> list, Context context) {
this.list = list;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_tester_test_list, parent, false);
return new ViewHolder(view);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
DataItem item = list.get(position);
//Name
holder.txt_name.setText(item.getTitle());
//Conditions
if (!App.isEmptyString(item.getOs()) && !App.isEmptyString(item.getType()) && !App.isEmptyString(item.getBrowser())) {
holder.txt_condition.setText(item.getType() + " | " + item.getOs() + " | " + item.getBrowser());
}
//Button actions
holder.setState(item.getState(), position);
//Price
holder.rowTests_priceTxt.setText(item.getPrice() + " Dollar");
//Animate items
Animation animation = AnimationUtils.loadAnimation(App.context,
(position > list.size() - 1) ? R.anim.down_from_top : R.anim.up_from_bottom);
holder.itemView.startAnimation(animation);
Toast.makeText(context, ""+list.get(0).getId(), Toast.LENGTH_SHORT).show();
}
#Override
public int getItemCount() {
return list.size();
}
public void add(List<DataItem> list) {
list.addAll(list);
notifyDataSetChanged();
}
public void clear() {
list.clear();
notifyDataSetChanged();
}
class ViewHolder extends RecyclerView.ViewHolder {
private ViewGroup root;
private TextView txt_name, txt_value, txt_condition, rowTests_priceTxt;
private RoundTextView rowTests_button;
ViewHolder(View view) {
super(view);
root = (ViewGroup) view;
txt_name = view.findViewById(R.id.txtTestListTitle);
txt_value = view.findViewById(R.id.txtTestListSublist);
txt_condition = view.findViewById(R.id.txtTestListSublist2);
rowTests_priceTxt = view.findViewById(R.id.rowTests_priceTxt);
rowTests_button = view.findViewById(R.id.rowTests_button);
}
}
How can i fix it?
You are adding data again in the same list passed in the parameter. Try to replace the below code
public void add(List<DataItem> list) {
list.addAll(list);
notifyDataSetChanged();
}
with
public void add(List<DataItem> list) {
this.list.addAll(list);
notifyDataSetChanged();
}
Clear the current list
Add the data to the adapter's list.
public void add(List<DataItem> list) {
clear();
this.list.addAll(list);
notifyDataSetChanged();
}
Your approach didn't work because you were updating the very list that you were passing in the function and not the adapter's list.
First add all data into list & than notify your adapter , after this set your adapter to recyclerview.
list.addAll(data)
adapter.notifyDataSetChanged()
val layoutManager = LinearLayoutManager(activity)
recyclerview.isNestedScrollingEnabled = false
recyclerview.layoutManager = layoutManager
recyclerview.itemAnimator = DefaultItemAnimator()
recyclerview.adapter = mAdapter

Select only one image in RecyclerView

I have a RecyclerView.Adapter which has some Arrays there.
ArrayList with Strings and ArrayList with Integer. Strings are like url and Integer is the photo.
When the app is open for first time the first item is selected.
I have another method for click which makes another item as selected and this works, but the problem is that the first item stays as selected and so for every image click makes as selected, I want only one item to be selected and take a color.
This is my code.
Adapter of RecyclerView
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem;
private ArrayList<Integer> mImages = new ArrayList<>();
private ArrayList<String> mSearchUrl = new ArrayList<>();
private Context mContext;
public ListViewAdapter(ArrayList<Integer> images, ArrayList<String> SearchUrl, Context context) {
mImages = images;
mContext = context;
mSearchUrl = SearchUrl;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.s_engine_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder viewHolder, final int i) {
selectedItem = 0;
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
Glide.with(mContext).load(mImages.get(i))
.into(viewHolder.image);
viewHolder.searchUrl.setText(mSearchUrl.get(i));
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
selectedItem = i;
}
});
}
#Override
public int getItemCount() {
return mImages.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView image;
TextView searchUrl;
public ViewHolder(#NonNull View itemView) {
super(itemView);
image = itemView.findViewById(R.id.ivEngine);
searchUrl = itemView.findViewById(R.id.ivEngineText);
}
}
}
And this is the MainActivity.class
public void intSearch() {
mImages.add(R.drawable.s_bing);
mSearchUrl.add("https://www.bing.com/search?q=");
mImages.add(R.drawable.s_google);
mSearchUrl.add("https://www.google.com/search?q=");
mImages.add(R.drawable.s_yahoo);
mSearchUrl.add("www.yahoo.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
mImages.add(R.drawable.amazon_white256);
mSearchUrl.add("www.amazon.com");
initRecyclerView();
}
private void initRecyclerView() {
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = findViewById(R.id.lvEngines);
recyclerView.setLayoutManager(layoutManager);
ListViewAdapter adapter = new ListViewAdapter(mImages, mSearchUrl, this);
recyclerView.setAdapter(adapter);
}
Initialize your selected item globally
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder>{
private int selectedItem = 0;
.....
Then inside your onBindViewHolder whenever you click a new Image notify your adapter for changes in the last selected item cell.
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int previousSelectedItem = selectedItem;
selectedItem = i;
notifyItemChanged(previousSelectedItem);
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}
});
Just remove this line from onBindViewHolder
selectedItem = 0;
and add an else to the background condition, like:
if (selectedItem == i) {
viewHolder.image.setBackgroundColor(Color.parseColor("#30000000"));
}else{
viewHolder.image.setBackgroundColor(“YOUR_DEFAULT_COLOR”);
}
and update the onClick:
viewHolder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedItem = i;
notifyDataSetChanged();
}
});

How to update Datamodel in RecyclerviewAdapter

i created a recyclerview where i can see all my chats. Every item contains the name, the lastmessage and a thumb. if the user send or receive a new message, it should be displayed there and the item should go to position 0. Now i have the problem that the message is displayed, but the chat item goes only to the first position if the position was not 0 before. So if i receive two new messages its not working anymore because the data model is the same like before. So how can i fit my data model to the current position of every item. Currently my adapter looks like this:
private static final String TAG = "CustomAdapter";
private Context context;
private Activity mActivity;
private List<MatchesObject> matchesList;
private String currentUid;
public matchadapterino(Activity mActivity, ArrayList<MatchesObject> mDataSet) {
this.mActivity = mActivity;
this.matchesList = mDataSet;
}
// Create new views (invoked by the layout manager)
#Override
public matchadapterino.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.matchesitem, viewGroup, false);
return new matchadapterino.ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final matchadapterino.ViewHolder viewHolder, final int position) {
viewHolder.getMatchname().setText(matchesList.get(position).getUsername());
if (!matchesList.get(position).getProfileImageUrl().equals("default")) {
Picasso.with(mActivity).load(matchesList.get(position).getProfileImageUrl()).into(viewHolder.getMatchImage());
getLastMSG(matchesList.get(position).getUserId(), viewHolder.getLastMSG(), position);
viewHolder.getMatchImage().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, UserDetailView.class);
//
i.putExtra("userId", matchesList.get(position).getUserId());
mActivity.startActivity(i);
}
});
} else {
viewHolder.getMatchImage().setImageResource(R.mipmap.ic_launcher_round);
}
viewHolder.getForeground().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mActivity, Chat.class);
Bundle b = new Bundle();
b.putString("matchId", matchesList.get(position).getUserId());
i.putExtras(b);
mActivity.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return matchesList.size();
}
// Get element from your dataset at this position and replace the contents of the view
// with that element
public void removeItem(int position) {
matchesList.remove(matchesList.get(position));
notifyItemRemoved(position);
}
// Return the size of your dataset (invoked by the layout manager)
/**
* Provide a reference to the type of views that you are using (custom ViewHolder)
*/
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView matchname, lastMSG;
public ImageView matchImage;
private RelativeLayout foreground;
private RelativeLayout background;
public ViewHolder(View v) {
super(v);
currentUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
matchname = itemView.findViewById(R.id.matchname);
matchImage = itemView.findViewById(R.id.matchImages);
lastMSG = itemView.findViewById(R.id.lastmsg);
foreground = itemView.findViewById(R.id.foregroundmatch);
background = itemView.findViewById(R.id.backgroundmatch);
}
public RelativeLayout getForeground() {
return foreground;
}
public RelativeLayout getBackground() {
return background;
}
public TextView getLastMSG() {
return lastMSG;
}
public TextView getMatchname() {
return matchname;
}
public ImageView getMatchImage() {
return matchImage;
}
}
private void getLastMSG(final String userId, final TextView lastMSG, final int position) {
final String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users").child(userid).child("connections").child("matches").child(userId);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
notifyItemMoved(0, position);
Toast.makeText(mActivity, "position changed" + position, Toast.LENGTH_LONG).show();
if (dataSnapshot.child("lastMsgBy").getValue().toString().equals(userid)) {
lastMSG.setTextColor(Color.parseColor("#d2403a3a"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
} else {
lastMSG.setTextColor(Color.parseColor("#000000"));
String lastMsg = dataSnapshot.child("lastMsg").getValue().toString();
lastMSG.setText(lastMsg);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}

How to update listview in tab?

I have two tabs in my app and there are listviews in this tabs.
I set List data to each listvew.
I want to delete form list, and from listview when I click [x] image.
Item deleted from list In my code , but I dont know how to update listview,I use notifyDataSetChanged() in my customadapter, but not update.
Activity for first tab:
public static List<Product> mCartList;
mCartList = AllProducts.getCartList();
listViewCatalog = (ListView) findViewById(R.id.my_order_list);
mProductAdapter = new CustomListAdapter(MyOrders.this, mCartList, "", true);
listViewCatalog.setAdapter(mProductAdapter);
my Custom List Adapter:
public class CustomListAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private Context mContext;
private List<Product> mProductList;
private String mType;
private boolean mShowQuantity;
public CustomListAdapter(Context context, List<Product> list, String type, boolean showQuantity) {
layoutInflater = LayoutInflater.from(context);
mContext = context;
mProductList = list;
mShowQuantity = showQuantity;
mType = type;
}
#Override
public int getCount() {
return mProductList.size();
}
#Override
public Object getItem(int position) {
return mProductList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder item;
final int finalMPosition = position;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_row, null);
item = new ViewHolder();
item.imageView = (ImageView) convertView.findViewById(R.id.product_image);
item.name = (TextView) convertView.findViewById(R.id.name);
item.pid = (TextView) convertView.findViewById(R.id.pid);
item.price = (TextView) convertView.findViewById(R.id.price);
item.description = (TextView) convertView.findViewById(R.id.description);
item.removeProduct = (ImageView) convertView.findViewById(R.id.removeProduct);
item.addToCart = (TextView) convertView.findViewById(R.id.addtocard);
item.productQuantity = (TextView) convertView.findViewById(R.id.textViewQuantity);
convertView.setTag(item);
} else {
item = (ViewHolder) convertView.getTag();
}
final Product curProduct = mProductList.get(position);
item.imageView.setImageDrawable(curProduct.imageView);
item.name.setText(curProduct.name);
item.pid.setText(curProduct.pid);
int length = curProduct.description.length();
int start = 0, end = length;
if (length >= 40) {
start = 0;
end = 40;
}
String s = curProduct.description.substring(start, end);
item.description.setText(s + "...");
item.price.setText(curProduct.price + mContext.getString(R.string.currency));
if (mShowQuantity) {
item.addToCart.setVisibility(View.GONE);
// item.productQuantity.setText("Quantity: " + AllProducts.getProductQuantity(curProduct));
item.productQuantity.setVisibility(View.GONE);
} else {
item.productQuantity.setVisibility(View.GONE);
item.removeProduct.setVisibility(View.GONE);
}
item.removeProduct.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
ab.setTitle("Delete ");
ab.setMessage("This product will be deleted from list.").setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
curProduct.selected = false;
AllProducts.removeProduct(curProduct);
notifyDataSetChanged();
notifyDataSetInvalidated();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
ab.create().show();
}
});
item.addToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent productDetailsIntent = new Intent(mContext, ProductDetail.class);
productDetailsIntent.putExtra(AllProducts.PRODUCT_INDEX, finalMPosition);
productDetailsIntent.putExtra("type", mType);
mContext.startActivity(productDetailsIntent);
}
});
return convertView;
}
public class ViewHolder {
TextView pid;
TextView addToCart;
TextView name;
TextView price;
TextView description;
ImageView imageView;
ImageView removeProduct;
TextView productQuantity;
}
}
You can introduce notifyDataSetChanged() in the list view or you can reset the setAdapter() which the new list values , but later one will be costly
You have 2 different List, try doing this:
Create a constructor without passing a List i mean:
CustomListAdapter(MyOrders.this, "", true);
Then in the CustomListAdapter create an List Local variable and instatiate it in the constructor:
private List<Product> mProductList;
public CustomListAdapter(Context context, String type, boolean showQuantity) {
layoutInflater = LayoutInflater.from(context);
mContext = context;
mProductList = new ArrayList<Product>();
mShowQuantity = showQuantity;
mType = type;
}
then create an Add or Delete method in the CustomListAdapter:
public void AddItem(Product product){
if(null != product){
mProductList.add(product);
}
}
Then an updateMethod too:
public void update(){
mProductList.notifyDataSetChanged();
}
if notifyDatasetChanged is not working try to use this
yourlist.invalidateviews();
You need to remove that particular item from arraylist by calling
AllProducts.remove(position);
notifyDatasetChanged();
write this methode in your adapter and use it to remove perticular Item from adapter.
public void remove(int position){
mProductList.remove(position);
notifyDatasetChanged();
}
I resolved my problem.
public static void setTab(int i){
if(i==0){
mTabHost.setCurrentTab(i+1);
mTabHost.setCurrentTab(i);
}
else{
mTabHost.setCurrentTab(i-1);
mTabHost.setCurrentTab(i);
}
}
and
#Override
public void onClick(DialogInterface dialog, int which) {
curProduct.selected = false;
AllProducts.removeProduct(curProduct);
MyTabActivity.setTab(0);
}
and for second listview:
MyTabActivity.setTab(1);
The only reason it is not working for you now, is because you have two different lists. You are removing from wrong list.
So first of all, do not delete from your list. Write a method in your adapter where you remove it from list you have stored in that Adapter, and then call notifyDatasetChanged in that method.
Working with tabs in android 2.x, I found a bug in the emulator: The tabs are not correctly refreshed or removed. Alternatives is to use support library v7 which as support for action bar tabs.
Use following code to update ListView.
In order to update ListView you must have to call notifyDataSetChanged(); menthod on Adapter. See Below code.
What you did.
notifyDataSetChanged();
notifyDataSetInvalidated();
What you have to do is,
yourAdapter.notifyDataSetChanged();
Or you may use following code to refresh your list.
private List<Object> mCarlistitem= new ArrayList<Object>();
public void refreshlist()
{
mCarlistitem.clear();
for(int i=0; i< mCartList.size(); i++)
{
Object object = new Object();
mCarlistitem.add(object);
}
mProductAdapter = new CustomListAdapter(MyOrders.this, mCartList, "",true);
listViewCatalog.setAdapter(mProductAdapter);
}

Categories