I have Recyclerview with Textview and Checkbox. Each item can be hidden or shown. In MainActivity, at run I show only items which are not hidden. But in menu I have an option called - show hidden items. at click I have t oshow also hidden Items, but with gray color.
HOw can I do it? how to reach Recyclerview's single item's properties from MainActivity ?
Here is my code:
RVAdapter
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.DataHolder> {
static String LOG = "RV_LOG";
ArrayList<DataObject> myData;
MainActivity mainActivity;
public static MyClickListener myClickListener;
public class DataHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
CompoundButton.OnCheckedChangeListener {
TextView text;
CheckBox checkBox;
private int position;
public DataHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(this);
}
public void setPosition(int value) {
this.position = value;
}
#Override
public void onClick(View v) {
myClickListener.onItemClick(position, v);
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mainActivity.onItemClick(position, buttonView, isChecked);
}
}
public void setOnItemClickListener(MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public RVAdapter(ArrayList<DataObject> myData, MainActivity mainActivity) {
this.myData = myData;
this.mainActivity=mainActivity;
}
#Override
public DataHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_single_item, parent, false);
return new DataHolder(view);
}
#Override
public void onBindViewHolder(final DataHolder holder, final int position) {
holder.text.setText(myData.get(position).getText());
holder.checkBox.setChecked(myData.get(position).getCheck());
if (myData.get(position).getHidden()) {
holder.text.setTextColor(Color.parseColor("#d6d6c2"));
holder.text.setVisibility(View.GONE);
holder.checkBox.setVisibility(View.GONE);
}
holder.setPosition(position);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public void addItem(DataObject object, int index) {
myData.add(index, object);
notifyItemInserted(index);
}
public void deleteItem(int index) {
myData.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return myData.size();
}
public interface MyClickListener {
public void onItemClick(int position, View v);
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
private RecyclerView myRecyclerView;
private RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager manager;
private ArrayList<DataObject> data;
String TAG = "MA Tag";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
data = new ArrayList<DataObject>();
boolean hidden = true;
for (int i = 0; i < 10; i++) {
DataObject object = new DataObject("Item No " + (i + 1), false, hidden);
data.add(i, object);
hidden = !hidden;
}
myRecyclerView = (RecyclerView) findViewById(R.id.rv);
myRecyclerView.setHasFixedSize(true);
adapter = new RVAdapter(data, this);
myRecyclerView.setAdapter(adapter);
manager = new LinearLayoutManager(this);
myRecyclerView.setLayoutManager(manager);
}
public void onItemClick(int position, View view, boolean isChecked) {
switch (view.getId()) {
case R.id.text:
Log.d(TAG, "item is clicked");
break;
case R.id.checkbox:
data.get(position).setCheck(isChecked);
Log.d(TAG, position + " is " + data.get(position).getCheck() + ":" + isChecked);
if (isChecked) {
data.get(position).setCheck(true);
} else {
data.get(position).setCheck(false);
Log.d(TAG, position + " is " + data.get(position).getCheck());
}
break;
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
for(int i = data.size()-1; i >=0; i--){
if(data.get(i).getCheck())
((RVAdapter) myRecyclerView.getAdapter()).deleteItem(data.indexOf(data.get(i)));
}
break;
case R.id.show:
Log.d(TAG, "Show");
for(int i = 0; i <data.size(); i++){
if(data.get(i).getHidden()){
Log.d(TAG, data.get(i).getText());
data.get(i).setHidden(false);
}
}
break;
}
return true;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.layout_menu, menu);
return true;
}
}
UPDATE:
now my RVAdapter looks so:
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.DataHolder> {
static String LOG = "RV_LOG";
ArrayList<DataObject> myData;
MainActivity mainActivity;
public class DataHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
CompoundButton.OnCheckedChangeListener, View.OnLongClickListener {
TextView text;
CheckBox checkBox;
private int position;
public DataHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(this);
text.setOnLongClickListener(this);
}
public void setPosition(int value) {
this.position = value;
}
#Override
public void onClick(View v) {
mainActivity.onItemClick(position, v, true);
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mainActivity.onItemClick(position, buttonView, isChecked);
}
#Override
public boolean onLongClick(View v) {
mainActivity.onLongClick(position);
return true;
}
}
public RVAdapter(ArrayList<DataObject> myData, MainActivity mainActivity) {
this.myData = myData;
this.mainActivity=mainActivity;
}
#Override
public DataHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_single_item, parent, false);
return new DataHolder(view);
}
#Override
public void onBindViewHolder(final DataHolder holder, final int position) {
holder.text.setText(myData.get(position).getText());
holder.checkBox.setChecked(myData.get(position).getCheck());
if (myData.get(position).getHidden()) {
holder.text.setVisibility(View.GONE);
holder.checkBox.setVisibility(View.GONE);
}
if(myData.get(position).getWasHidden()){
holder.text.setTextColor(Color.parseColor("#666666"));
}
holder.setPosition(position);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public void deleteItem(int index) {
myData.remove(index);
notifyItemRemoved(index);
notifyItemRangeChanged(index, myData.size());
}
public void hideItem(int position){
myData.get(position).setHidden(true);
}
public void showItem(int position){
myData.get(position).setHidden(false);
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return myData.size();
}
}
in my Activity I call showItem() method.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
for(int i = data.size()-1; i >=0; i--){
if(data.get(i).getCheck())
((RVAdapter) myRecyclerView.getAdapter()).deleteItem(data.indexOf(data.get(i)));
}
break;
case R.id.show:
for(int i = 0; i< data.size(); i++) {
if(data.get(i).getHidden())
((RVAdapter) myRecyclerView.getAdapter()).showItem(i);
}
adapter.notifyDataSetChanged();
break;
}
return true;
}
It works a bit wrong: At run every second item is shown(correct, cause every second is not hidden). When I tap on Show, hidden items appear, but first two shown items disappear. when I tap on Show again, they appear. what is wrong here?
Create a method inside the adapter to show the hidden items. Since you have the adapter object inside your Main Activity you can easily call that method from inside your Main Activity. After calling that method, call notifyDataSetChanged() method from your MainActivity itself. notifyDataSetChanged() method will be called by the adapter object.
Related
I am using a RecyclerView and an adapter to display the data of an array of Classes objects. I have a MainHolder and two subHolders - ItemHolder and HeaderHolder. ItemHolder has Checkbox. In RecyclerView, I use a CheckBox for one of the object's parameters. How can I save it? For the rest I use SharedPreferences, but here I don't know how to apply it in my Activity.
Here's my MainHolder:
public abstract class MainHolder extends RecyclerView.ViewHolder {
abstract void setData(MainItem item);
public MainHolder(#NonNull View itemView) {
super(itemView);
}
}
And ItemHolder:
public class ItemHolder extends MainHolder{
private TextView tvTitle, tvComment, tvDate;
private CheckBox cbImportance;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
#Override
void setData(MainItem item) {
final Event event = item.getEventItem();
tvTitle.setText(event.getName());
tvComment.setText(event.getComment());
tvDate.setText(simpleDateFormat.format(event.getDate()));
cbImportance.setOnCheckedChangeListener(null);
cbImportance.setChecked(event.getImportant());
cbImportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
event.IsImportant = b;
}
});
}
public ItemHolder(#NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvComment = itemView.findViewById(R.id.tvComment);
tvDate = itemView.findViewById(R.id.tvDate);
cbImportance = itemView.findViewById(R.id.cbIconImportant);
}
}
Here's my Adapter
public class MainAdapter extends RecyclerView.Adapter<MainHolder> {
private Context context;
private ArrayList<MainItem> data;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
private OnItemCheckedListener mOnItemChecked;
public interface OnItemCheckedListener{
void onItemChecked(int position, boolean isImportant);
}
public void setOnItemCheckedListener(OnItemCheckedListener listener){
mOnItemChecked = listener;
}
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
public MainAdapter(Context context, ArrayList<MainItem> data) {
this.context = context;
this.data = data;
}
#NonNull
#Override
public MainHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType){
case (Constants.ITEM_HEADER_TEXT_VIEWTYPE):
view = LayoutInflater.from(context).inflate(R.layout.group_layout, parent, false);
return new HeaderHolder(view);
case (Constants.ITEM_EVENT_TEXT_VIEWTYPE):
view = LayoutInflater.from(context).inflate(R.layout.list_item_cardview, parent, false);
return new ItemHolder(view);
default: throw new IllegalArgumentException();
}
}
#Override
public void onBindViewHolder(#NonNull final MainHolder holder, final int position) {
holder.setData(data.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.getItemViewType() == Constants.ITEM_HEADER_TEXT_VIEWTYPE)
Toast.makeText(context, "Нажал на заголовок" + position, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Нажал на айтем" + position, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemViewType(int position) {
return data.get(position).getViewType();
}
Ok, I made the checkbox public in ItemHolder.
And in OnBindHolder I made OnCheckedChanged for Checkbox
#Override
public void onBindViewHolder(#NonNull final MainHolder holder, final int position) {
holder.setData(data.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.getItemViewType() == Constants.ITEM_HEADER_TEXT_VIEWTYPE)
Toast.makeText(context, "Нажал на заголовок" + position, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Нажал на айтем" + position, Toast.LENGTH_SHORT).show();
}
});
if (holder.getItemViewType() == Constants.ITEM_EVENT_TEXT_VIEWTYPE){
((ItemHolder) holder).cbImportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
data.get(position).getEventItem().IsImportant = b;
if (b){
Toast.makeText(context, "IMPORTANT", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(context, "NON IMPORTANT", Toast.LENGTH_SHORT).show();
}
notifyDataSetChanged();
mOnItemChecked.onItemChecked(position, b);
}
});
}
}
In the fragment I write state of the checkbox.
adapterEvent.setOnItemCheckedListener(new MainAdapter.OnItemCheckedListener() {
#Override
public void onItemChecked(int position, boolean isImportant) {
write(getContext(), events, PROCESSED_EVENTS);
ShowEvents(ShowMode);
}
});
I have some problems with RecyclerView Adapter. I want to do the list with id index: 1,2,3... When an item is removed it should set every next item position to position-1. Like this: (for example delete number 3)
1|2|3|4|5 -> 1|2|3|4
It works perfectly when:
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
But this causes other errors with notifyItemRemoved().
When I set:
#Override
public long getItemId(int position) {
return 0;
}
#Override
public int getItemViewType(int position) {
return 0;
}
It has problems with item order after scrolling, with repeatability of numbers etc.
I'm stuck.
MainActivity.class
public class MainActivity extends AppCompatActivity {
private DatabaseHelper databaseHelper;
private EditText editText;
private Button showButton,saveButton;
private RecyclerView mainListRecyclerView;
private ArrayList<String>arrayList;
private MainListAdapter mainListAdapter;
private RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
showButton = (Button) findViewById(R.id.showButton);
saveButton = (Button) findViewById(R.id.saveButton);
mainListRecyclerView = (RecyclerView) findViewById(R.id.listView);
databaseHelper = new DatabaseHelper(this);
arrayList = new ArrayList<>(20);
layoutManager = new LinearLayoutManager(this);
mainListRecyclerView.setLayoutManager(layoutManager);
mainListAdapter = new MainListAdapter(arrayList,this);
mainListAdapter.setHasStableIds(false);
mainListRecyclerView.setAdapter(mainListAdapter);
mainListAdapter.notifyDataSetChanged();
showButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FinalListActivity.class);
intent.putExtra("productList",arrayList);
MainActivity.this.startActivity(intent);
}
});
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_DONE) {
addItem();
}
return true;
}
});
}
public void addData(String newItem){
boolean insertData = databaseHelper.addData(newItem);
if(insertData){
toastMessage("Item successfully inserted!");
}
else {
toastMessage("Something is wrong");
}
}
public void removeData(String itemToRemove){
boolean removeData = databaseHelper.removeData(itemToRemove);
if(removeData){
toastMessage("Item successfully deleted!");
}
else {
toastMessage("Something is wrong");
}
}
public void toastMessage(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
public void addItem(){
String newItem = editText.getText().toString();
if(newItem.length()!=0) {
addData(newItem);
arrayList.add(newItem);
editText.setText("");
editText.requestFocus();
mainListAdapter.notifyItemInserted(arrayList.size()-1);
}
else{
toastMessage("You must put something in the text field");
}
}
public void removeItem(int position){
if(mainListAdapter.getItemCount()!=0){
removeData(arrayList.get(position));
arrayList.remove(position);
mainListAdapter.notifyItemRemoved(position);
}
}
}
Adapter class
public class MainListAdapter extends
RecyclerView.Adapter<MainListAdapter.MyViewHolder> {
private ArrayList<String> mDataset;
private MainActivity mainActivity;
public MainListAdapter(ArrayList<String> mDataset, MainActivity
mainActivity) {
this.mDataset = mDataset;
this.mainActivity = mainActivity;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public int getItemViewType(int position) {
return 0;
}
#Override
public int getItemCount() {
return mDataset.size();
}
#Override
public void onBindViewHolder(final MyViewHolder holder,final int position) {
holder.listTextView1.setText(holder.getAdapterPosition()+"");
holder.listTextView2.setText(mDataset.get(position));
holder.listButtonViewDel.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
int currentPosition = holder.getAdapterPosition();
if(currentPosition!=-1)
mainActivity.removeItem(currentPosition);
}
});
}
public class MyViewHolder extends RecyclerView.ViewHolder {
final public TextView listTextView1;
final public TextView listTextView2;
final public Button listButtonViewDel;
public MyViewHolder(View view) {
super(view);
listTextView1 = (TextView) view.findViewById(R.id.listTextView1);
listTextView2 = (TextView) view.findViewById(R.id.listTextView2);
listButtonViewDel = (Button) view.findViewById(R.id.listButtonViewDel);
}
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_list_layout, parent, false);
return new MyViewHolder(view);
}
}
Add this lines To removeItem function in MainActivity.java
public void removeItem(int position){
if(mainListAdapter.getItemCount()!=0){
removeData(arrayList.get(position));
arrayList.remove(position);
mainListAdapter.notifyItemRemoved(position);
arrayList.remove(position); // add this line
mainListAdapter.update(arrayList); // add this line
}
}
And add update function to your MainListAdapter.java like this
public void update(ArrayList<String> mDataset){
this.mDataset = mDataset
notifyDataSetChanged();
}
For show animation try this function (I suggest you to set all function about adapter in adapter)
public void update(ArrayList<String> mDataset,int position){
this.mDataset = mDataset
notifyItemRangeChanged(position,mDataset.size);
}
In your removeItem() method,
You have mainListAdapter.notifyItemRemoved(position); and it will only inform the item is removed.
You need to put a line inside this method at end as mainListAdapter.notifyDataSetChanged().
It reminds adapter to reset the list on every change.
you can set null to mainListRecyclerVie wadapter and bind again when remove items !
mainListRecyclerVie.setAdapter(null);
and bind again
My Code is:
JSONArray jsonArray=new JSONArray(response);
if(jsonArray.length()==0){
Toast.makeText(context,"No Data",Toast.LENGTH_SHORT).show();
}else {
for (int i = 0; i < jsonArray.length(); i++) {
innerListData = new TakeAttendanceModel();
innerListData = ((TakeAttendanceModel) JSonUtil.jsonToObject(jsonArray.getString(i), TakeAttendanceModel.class));
innerListData.status = "P";
innerListData.attendanceDate = DateTimeUtils.getDate();
attenList.add(innerListData);
}
submitAtten=(Button)rootView.findViewById(R.id.takeAttendanceSubmit);
submitAtten.setVisibility(View.VISIBLE);
}
Log.d("Responsse : ", response);
}
takeAttendanceAdapter = new TakeAttendanceAdapter(context,attenList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerViewAttendanceList.setLayoutManager(mLayoutManager);
recyclerViewAttendanceList.setItemAnimator(new DefaultItemAnimator());
recyclerViewAttendanceList.setAdapter(takeAttendanceAdapter);
takeAttendanceAdapter.notifyDataSetChanged();
My Adapter code is:
private List<TakeAttendanceModel> list;
public TakeAttendanceAdapter(Context context, List<TakeAttendanceModel> list) {
this.context = context;
this.list = list;
}
#Override
public AttendanceListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View convertview = LayoutInflater.from(parent.getContext())
.inflate(R.layout.inner_list_attendance, parent, false);
return new AttendanceListViewHolder(convertview);
}
#Override
public void onBindViewHolder(final AttendanceListViewHolder holder, final int position) {
holder.textViewStudentName.setText(list.get(position).studFullName);
holder.textViewStudentRollNumber.setText(list.get(position).primaryKey);
holder.texViewStudentPreFix.setText(list.get(position).prefix);
holder.SSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
//final LinkedList<String> innerLinklist=new LinkedList<>();
if (isChecked) {
/*innerLinklist.add(list.get(position).primaryKey);
innerLinklist.add(list.get(position).studFullName);
innerLinklist.add(list.get(position).status="P");*/
// linkedList.add(innerLinklist);
//Log.v("Attndce Liist After Toggle",linkedList.toString());
list.get(position).status="P";
} else {
/*innerLinklist.add(list.get(position).primaryKey);
innerLinklist.add(list.get(position).studFullName);
innerLinklist.add(list.get(position).status="A");*/
// linkedList.add(innerLinklist);
//Log.v("Attndce Liist After Toggle",linkedList.toString());
list.get(position).status="A";
}
Log.v("Attndce Inner",list.toString());
//DataManager.factory().linkedList.add(innerLinklist);
//Log.v("Attndce Full Linklist",DataManager.factory().linkedList.toString());
}
});
//Log.v("Attndce Liist After Toggle",DataManager.factory().linkedList.toString());
}
#Override
public int getItemCount() {
return list.size();
}
public class AttendanceListViewHolder extends RecyclerView.ViewHolder {
/*public ImageView imageViewProfilePic;*/
public TextView textViewStudentName, textViewStudentRollNumber,texViewStudentPreFix;
public SwitchCompat SSwitch;
public AttendanceListViewHolder(View convertview) {
super(convertview);
texViewStudentPreFix=(TextView)convertview.findViewById(R.id.textAttendanceStudentPrfix) ;
textViewStudentName = (TextView) convertview.findViewById(R.id.textViewAttendanceStudentName);
textViewStudentRollNumber = (TextView) convertview.findViewById(R.id.textViewAttendanceStudentRollno);
SSwitch = (SwitchCompat) convertview.findViewById(R.id.textViewAttendanceSwitch);
}
}
This is My adapter code in which switch is placed.
Actually in RecylerView I place a Switch button and when switch button is on at 0 position then Automatically switch is ON after 9th position.
Please give me a solution.
First things first, make a proper POJO class for your adapter.
never use something like list.get(position).variable instead of this make your variable as private and use setters and getters like list.get(position).getVariable() or list.get(position).setVariable(variable)
Then as you know, since RecyclerView always recycle the views, its advisable to use if followed by else for every UI change. In your case you are just changing the switch condition without resetting it anywhere.
And the most important part, never use the position that is passed as
a paremeter. Instead use the adapter position as I specified in the
solution
Check the updated code below:
#Override
public void onBindViewHolder(final AttendanceListViewHolder holder, final int position) {
final int adapterPosition = holder.getAdapterPosition();
holder.textViewStudentName.setText(list.get(adapterPosition).studFullName);
holder.textViewStudentRollNumber.setText(list.get(adapterPosition).primaryKey);
holder.texViewStudentPreFix.setText(list.get(adapterPosition).prefix);
holder.SSwitch.setSelected(list.get(adapterPosition).getStatus());
holder.SSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
list.get(adapterPosition).setStatus(isChecked);
notifyItemChanged(adapterPosition);
Log.v("Attndce Inner",list.toString());
}
});
}
Update code is:
#Override
public void onBindViewHolder(final AttendanceListViewHolder holder, int position) {
final int adapterPosition = holder.getAdapterPosition();
holder.textViewStudentName.setText(list.get(adapterPosition).studFullName);
holder.textViewStudentRollNumber.setText(list.get(adapterPosition).primaryKey);
holder.texViewStudentPreFix.setText(list.get(adapterPosition).prefix);
holder.SSwitch.setSelected(list.get(adapterPosition).getStatus());
holder.SSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
list.get(adapterPosition).setStatus(isChecked);
notifyItemChanged(adapterPosition);
Log.v("Attndce Inner",list.toString());
//Log.v("Attndce Full Linklist",DataManager.factory().linkedList.toString());
}
});
Model Class is:
public class TakeAttendanceModel {
public String primaryKey;
public String prefix;
public String studFullName;
public String attendanceDate;
public boolean status;
public boolean getStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
How can handle with this situation -> I have a list of itens in a recyclerView and I want to choose one of those option: green, yellow or red face to get the value of object from list item I chose
So I thought something like bellow, but when I select one of those faces anything happens. I think that button click listener doesn't work. Please someone can drive me to a better suggestion that works, give me an example or could me tell what am I doing wrong?
My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private SparseBooleanArray selectedItems;
public LikeListAdapter(List<Goals> goalsList) {
this.goalsList = goalsList;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
return new LikeItemViewHolder(view);
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("fretgr", "get Green Point = " + goals.getGreenPoint());
setToggleSelection(1);
}
});
holder.sosoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("rtret", "get Yellow Point = " + goals.getYellowPoint());
setToggleSelection(2);
}
});
holder.angryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("ewwr", "get Red Point = " + goals.getRedPoint());
setToggleSelection(3);
}
});
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
// method to access in activity after updating selection
public List<Goals> getGoalsList() {
return goalsList;
}
public void setToggleSelection(int pointType){
selectedItems = new SparseBooleanArray();
if (selectedItems.get(pointType, false)) {
selectedItems.delete(pointType);
} else {
selectedItems.put(pointType, true);
}
notifyItemChanged(pointType);
}
public int getToggleSelection(){
return 0;
}
}
My Fragment
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
assocGoalsRecyclerView.addOnItemTouchListener(RecycleTouchListener);
private RecyclerView.OnItemTouchListener RecycleTouchListener = new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = assocGoalsRecyclerView.findChildViewUnder(e.getX(), e.getY());
if(child!=null && mGestureDetector.onTouchEvent(e)){
final int position = assocGoalsRecyclerView.getChildAdapterPosition(child);
final Goals goals = associateList.get(position);
final Categories c = categoriesList.get(position);
final int type = likeListAdapter.getToggleSelection();
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) { }
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
};
I found an answer based in another responses and sugestions!!! Android: handling clicks on image view inside recycler's view item using touch framework
In My Fragment
Snippet from fragment:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
// assocGoalsRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList, onItemClickCallback);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
public static class OnItemClickListener implements View.OnClickListener {
private int position;
private OnItemClickCallback onItemClickCallback;
public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
this.position = position;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public void onClick(View view) {
onItemClickCallback.onItemClicked(view, position);
}
public interface OnItemClickCallback {
void onItemClicked(View view, int position);
}
}
private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
#Override
public void onItemClicked(View view, int position) {
switch(view.getId()){
case R.id.happy:
Log.e("rtetre", "happy assessed and position is = " + position);
break;
case R.id.soso:
Log.e("rwere", "soso assessed and position is = " + position);
break;
case R.id.angry:
Log.e("dfrefgt", "angry assessed and position is = " + position);
break;
}
}
};
In My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback;
public LikeListAdapter(List<Goals> goalsList, LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback) {
this.goalsList = goalsList;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
LikeItemViewHolder likeItemViewHolder = new LikeItemViewHolder(view);
return likeItemViewHolder;
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.sosoButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.angryButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public static class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
I have a Fragment which inflates a Recyclerview and populates it using an adapter. Now the layout has a Checkbox Item. Instead of handling the Checkbox Item click event in the Adapter in onBindViewHolder, I want to handle it in the Fragment class that implements the setOnCheckedChangeListener.
Is it possible to delegate the checked change event to the Fragment?
Here is the code -
Adapter class which populates the Cardview
public class CardTypesAdapter extends RecyclerView.Adapter<CardTypesAdapter.ViewHolder> {
private int[] arrCardID;
private String[] arrCardType;
private String[] arrCardSummary;
private Listener listener;
ArrayList<String> selectedStrings = new ArrayList<String>();
public static interface Listener {
public void onClick(int position);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private CardView cv;
public ViewHolder(CardView v) {
super(v);
cv = v;
}
}
public CardTypesAdapter(int[] arrCardID, String[] arrCardType, String[] arrCardSummary) {
this.arrCardID = arrCardID;
this.arrCardType = arrCardType;
this.arrCardSummary = arrCardSummary;
}
public void setListener(Listener listener) {
this.listener = listener;
}
#Override
public CardTypesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
CardView cv = (CardView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_types, parent, false);
return new ViewHolder(cv);
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
//Log.d("position in bindview", ""+ position);
CardView cv = holder.cv;
final CheckBox chbCardSelect = (CheckBox) cv.findViewById(R.id.chbCardSelect);
chbCardSelect.setId(arrCardID[position]);
chbCardSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
selectedStrings.add("" + chbCardSelect.getId());
} else {
selectedStrings.remove("" + chbCardSelect.getId());
}
Log.d("Selected Id" , ""+chbCardSelect.getId());
}
});
chbCardSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//onCheckedChanged(buttonView, isChecked);
if (isChecked) {
selectedStrings.add("" + chbCardSelect.getId());
} else {
selectedStrings.remove("" + chbCardSelect.getId());
}
Log.d("Selected Id" , ""+chbCardSelect.getId());
}
});
TextView txtCardName = (TextView) cv.findViewById(R.id.txtCardName);
txtCardName.setText(arrCardType[position]);
TextView txtCardSummary = (TextView) cv.findViewById(R.id.txtCardSummary);
txtCardSummary.setText(arrCardSummary[position]);
cv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("in ClickListener", "i am clicked");
if (listener != null) {
Log.d("in ClickListener", "i am clicked");
listener.onClick(position);
}
}
});
}
#Override
public int getItemCount() {
return arrCardType.length;
}
}
DialogFragment Class , where I plan to receive the Checkbox Click event
public class CardsTypeFragment extends DialogFragment implements View.OnClickListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_card_types, container, false);
//Recyclerview code
final RecyclerView cardtypeRecycler = (RecyclerView) view.findViewById(R.id.cards_types_recycler);
Button btnApplyFilter=(Button) view.findViewById(R.id.btnApplyFilter);
btnApplyFilter.setOnClickListener(this);
int[] arrCardID=new int[clsCardTypes.arrCardTypes.length];
String[] arrCardType = new String[clsCardTypes.arrCardTypes.length];
String[] arrCardSummary = new String[clsCardTypes.arrCardTypes.length];
for (int i = 0; i < arrCardType.length; i++) {
arrCardID[i] = clsCardTypes.arrCardTypes[i].getIntCardID();
arrCardType[i] = clsCardTypes.arrCardTypes[i].getStrCardType();
arrCardSummary[i] = clsCardTypes.arrCardTypes[i].getStrCardSummary();
}
CardTypesAdapter adapter = new CardTypesAdapter(arrCardID, arrCardType, arrCardSummary);
cardtypeRecycler.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this.getActivity(), LinearLayoutManager.VERTICAL,false);
cardtypeRecycler.setLayoutManager(layoutManager);
adapter.setListener(new CardTypesAdapter.Listener() {
public void onClick(int position) {
Log.d("in ClickListener", "i am clicked");
}
});
return view;
}
#Override
public void onClick(View view){
if(view.getId()==R.id.btnApplyFilter){
Intent i=new Intent()
.putExtra("name", "Amit Pandey")
.putExtra("age", "36");
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i);//getActivity().getIntent()
dismiss();
}
}
}
There were lots of examples of communication between Fragment and Activity. But very few between Adapters and Fragment.
I declared a interface in adapter -
public interface FragmentCommunicator{
public void passDataToFragment(String someValue);
}
Implemented it in my Fragment Class -
public class CardsTypeFragment extends DialogFragment implements View.OnClickListener, CardTypesAdapter.FragmentCommunicator
Passed it to the adapter -
CardTypesAdapter adapter = new CardTypesAdapter(arrCardID, arrCardType, arrCardSummary, this);
And inside the Adapter -
public CardTypesAdapter(int[] arrCardID, String[] arrCardType, String[] arrCardSummary, FragmentCommunicator fragmentCommunicator) {
this.arrCardID = arrCardID;
this.arrCardType = arrCardType;
this.arrCardSummary = arrCardSummary;
this.fragmentCommunicator=fragmentCommunicator;
}
and onCheckedChangeListener of the checkbox
chbCardSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Calling interface too-
if(fragmentCommunicator != null)
fragmentCommunicator.passDataToFragment("Hi from FragmentActivity");
else
Log.d("Msg", "not exists");
}
});