Listener in Android Studio RecyclerView custom adapter is returning null.
This is the Interface
private OnItemClickListener mlistener;
public interface OnItemClickListener{
void onItemClick(int position, Boolean paid);
}
public void setOnItemClickListener(OnItemClickListener listener){
mlistener = listener;
}
And this is the View Holder with the Listener. This is intended to pass a Boolean to the main activity.
public CartViewHolder(View itemView, ArrayList<Shift> shifts, OnItemClickListener listener) {
super(itemView);
paid = itemView.findViewById(R.id.due_back_paid);
containerView = itemView.findViewById(R.id.container);
paid.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position, isChecked);
}
}
}
});
containerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Shift current = (Shift)containerView.getTag();
Intent intent = new Intent(v.getContext(), ViewShiftActivity.class);
intent.putExtra("thisShift", current);
intent.putExtra("shifts", shifts);
v.getContext().startActivity(intent);
}
});
}
}
public LoadAdapter(ArrayList<Shift> shifts){
shiftList = shifts;
}
#NonNull
#Override
public CartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shift_row, parent, false);
CartViewHolder mvh = new CartViewHolder(view, shiftList, mlistener);
return mvh;
}
I have used this code in other projects and it works. I have can't seem to figure out what I am missing.
I've been asked to include the activity. The following is this code.
I have not added any code to the onItemClick here yet. waiting for the listener to work.
public class EditShiftActivity extends AppCompatActivity implements LoadAdapter.OnItemClickListener{
private ArrayList<Shift> shifts;
private RecyclerView lRecyclerView;
private LoadAdapter lAdapter;
private RecyclerView.LayoutManager lLayoutManager;
private View view;
private FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_shift);
Intent intent = getIntent();
shifts = intent.getParcelableArrayListExtra("shifts");
fab = findViewById(R.id.add_shift_edit);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(EditShiftActivity.this, AddShiftActivity.class);
intent1.putExtra("shifts", shifts);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
v.getContext().startActivity(intent1);
}
});
lRecyclerView = findViewById(R.id.shift_recycler);
lLayoutManager = new LinearLayoutManager(this);
lAdapter = new LoadAdapter(shifts);
lRecyclerView.setLayoutManager(lLayoutManager);
lRecyclerView.setAdapter(lAdapter);
}
#Override
public void onItemClick(int position, Boolean paid) {
}
}
Add below line in your code -
lAdapter = new LoadAdapter(shifts);
lAdapter.setOnItemClickListener(this);
You are retrieving the ArrayList<Shifts> from Intent. Check the size of shifts arraylist before sending to the Adapter. There is a chance that if the arraylist passed is empty then the adapter will return null and hence lRecyclerView will not be displayed.
Add this condition before passing data to adapter
//condition to check whether the arraylist is empty or not
if(!shifts.isEmpty()) {
lAdapter = new LoadAdapter(shifts);
//initialising the adapter
lRecyclerView.setAdapter(lAdapter);
}
Related
I'm trying to implement RecyclerView onclick listener, but it is not working. I've tried a lot, and try to implement other way too, but not working at all.
My Main Class:
public class MainMenuDashboard extends AppCompatActivity{
private RecyclerView recyclerMenu;
private RecyclerViewMenuAdapter menuAdapter;
private Call<CategoryModel> categoryModelCall;
private TokenManager tokenManagerMainMenu;
private ApiService serviceMainMenu;
List<CategoryModel.Subset> menuList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu_dashboard);
tokenManagerMainMenu = TokenManager.getInstance(getSharedPreferences("prefs", MODE_PRIVATE));
serviceMainMenu = RetrofitBuilder.createServiceWithAuth(ApiService.class, tokenManagerMainMenu);
recyclerMenu = findViewById(R.id.recyclerMenu);
menuList = new ArrayList<>();
GridLayoutManager layoutManager = new GridLayoutManager(MainMenuDashboard.this, 2, GridLayoutManager.VERTICAL, false);
recyclerMenu.setLayoutManager(layoutManager);
menuAdapter = new RecyclerViewMenuAdapter(menuList);
recyclerMenu.setAdapter(menuAdapter);
menuAdapter.notifyDataSetChanged();
mainMenuDashBoardToolbar = findViewById(R.id.mainMenuDashBoardToolbar);
setSupportActionBar(mainMenuDashBoardToolbar);
menuContent();
}
private void menuContent() {
categoryModelCall = serviceMainMenu.menuContent(incomingRoleId, true);
categoryModelCall.enqueue(new Callback<CategoryModel>() {
#Override
public void onResponse(#NotNull Call<CategoryModel> call, #NotNull Response<CategoryModel> response) {
if (response.isSuccessful() && response.body() != null && response.code() != 400) {
//findViewById(R.id.shimmerCategory).setVisibility(View.GONE);
CategoryModel categoryModel = response.body();
menuList = categoryModel.getSubset();
menuAdapter = new RecyclerViewMenuAdapter(menuList);
recyclerMenu.setAdapter(menuAdapter);
//menuAdapter.notifyDataSetChanged();
menuAdapter.setOnItemClickListener(new RecyclerViewMenuAdapter.ClickListenerMenu() {
#Override
public void onClick(int position) {
Toast.makeText(MainMenuDashboard.this, "Position "+position+" Clicked", Toast.LENGTH_SHORT).show();
menuAdapter.notifyDataSetChanged();
}
});
menuAdapter.notifyDataSetChanged();
}else {
if (response.code() == 401) {
Intent i = new Intent(MainMenuDashboard.this, MainActivity.class);
i.putExtra("USER_SESSION", true);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
tokenManagerMainMenu.deleteToken();
startActivity(i);
finish();
}
}
}
#Override
public void onFailure(#NotNull Call<CategoryModel> call, #NotNull Throwable t) {
}
});
}
}
My Adapter:
public class RecyclerViewMenuAdapter extends RecyclerView.Adapter<RecyclerViewMenuAdapter.RecyclerViewHolder> {
private static final String TAG = "NotesRecyclerAdapter";
private List<CategoryModel.Subset> subsetsCategories;
private ClickListenerMenu mClickListener;
private Context context;
public RecyclerViewMenuAdapter(List<CategoryModel.Subset> subsetsCategories) {
this.subsetsCategories = subsetsCategories;
}
#NonNull
#Override
public RecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_main_menu_category, parent, false);
return new RecyclerViewHolder(view, mClickListener);
}
#Override
public void onBindViewHolder(#NonNull final RecyclerViewHolder viewHolder, final int position) {
String menuCategoryImage = subsetsCategories.get(position).getIcon();
Picasso.get().load(menuCategoryImage).placeholder(R.drawable.admin).into(viewHolder.menuThumb);
String menuCategoryName = subsetsCategories.get(position).getName();
viewHolder.menuName.setText(menuCategoryName);
//Item click
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
mClickListener.onClick(position);
//Toast.makeText(context, "Position "+position+" Clicked", Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return subsetsCategories.size();
}
public static class RecyclerViewHolder extends RecyclerView.ViewHolder{
ImageView menuThumb;
TextView menuName;
private ClickListenerMenu mListener;
//ClickListenerMenu clickListenerMenu;
public RecyclerViewHolder(View view, ClickListenerMenu clickListenerMenu) {
super(view);
menuThumb = view.findViewById(R.id.menuThumb);
menuName = view.findViewById(R.id.menuName);
mListener = clickListenerMenu;
}
}
public void setOnItemClickListener(ClickListenerMenu clickListener) {
mClickListener = clickListener;
}
public interface ClickListenerMenu {
void onClick(int position);
}
}
I still can't find where I did wrong!! Any insight will be very appreciated
Thank You
Add item click listener in your adapter.
#Override
public void onBindViewHolder(#NonNull RecyclerViewHolder viewHolder, int position) {
String menuCategoryImage = subsetsCategories.get(position).getIcon();
Picasso.get().load(menuCategoryImage).placeholder(R.drawable.admin).into(viewHolder.menuThumb);
String menuCategoryName = subsetsCategories.get(position).getName();
viewHolder.menuName.setText(menuCategoryName);
//Item click
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
// Do something
}
});
}
Initialise your recycler view outside and put this line menuAdapter.notifyDataSetChanged(); where you add data in your list.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu_dashboard);
tokenManagerMainMenu = TokenManager.getInstance(getSharedPreferences("prefs", MODE_PRIVATE));
serviceMainMenu = RetrofitBuilder.createServiceWithAuth(ApiService.class, tokenManagerMainMenu);
recyclerMenu = findViewById(R.id.recyclerMenu);
menuList = new List<CategoryModel.Subset>();
GridLayoutManager layoutManager = new GridLayoutManager(MainMenuDashboard.this, 2, GridLayoutManager.VERTICAL, false);
recyclerMenu.setLayoutManager(layoutManager);
menuAdapter = new RecyclerViewMenuAdapter(menuList);
recyclerMenu.setAdapter(menuAdapter);
menuAdapter.notifyDataSetChanged();
menuContent();
}
I hope this can help you!
Add these line in the onBindViewHolder() method:
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//remove this lines
//mClickListener.onClick(position);
//notifyDataSetChanged();
//add this
context.startActivity(new Intent(context,SecondActivity.class))
}
});
and in your MainMenuDashboard class, initialize your Adapter like this:
menuAdapter = new RecyclerViewMenuAdapter(this,menuList);
also change your Adapter constructor like this:
public RecyclerViewMenuAdapter(Context context,List<CategoryModel.Subset> subsetsCategories) {
this.subsetsCategories = subsetsCategories;
this.context = context;
}
```
public class MainActivity extends Activity implements
GetDataContract.View,RecyclerItemClickListener {
private Presenter mPresenter;
RecyclerView recyclerView;
LinearLayoutManager linearLayoutManager;
CountryAdapter countryAdapter;
EditText etEnterName;
Button btAddItem;
List<CountryRes> allCountriesEditValue;
List<CountryRes> allCountriesData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getView();
}
private void getView() {
/*presentator */
mPresenter = new Presenter(this);
/*initiliaze of id*/
recyclerView = (RecyclerView) findViewById(R.id.recycler);
etEnterName = (EditText) findViewById(R.id.etEnterName);
btAddItem = (Button) findViewById(R.id.btAddItem);
linearLayoutManager = new LinearLayoutManager(this);
/*initiliaze the arraylist*/
allCountriesData=new ArrayList<>();
recyclerView.setLayoutManager(linearLayoutManager);
btAddItem.setOnClickListener(new AddButtonClick());
}
#Override
public void onGetDataFailure(String message) {
Log.d("Status", message);
}
#Override
public void onGetDataSuccess(String message, List<CountryRes>
allCountriesData) {
/*add the value mannulay*/
CountryRes countryRes = new CountryRes();
countryRes.setName(etEnterName.getText().toString());
allCountriesData.add(countryRes);
countryAdapter = new CountryAdapter(getApplicationContext(),
allCountriesData, (RecyclerItemClickListener) this);
recyclerView.setAdapter(countryAdapter);
/*set the data in the room*/
AppDataBase database = AppDataBase.getAppDatabase(this);
DataGenerator.with(database).generateCats(allCountriesData);
Logger.displayCatsInLog(database.catDao().loadAll());
countryAdapter.notifyDataSetChanged();
}
/*on item click*/
#Override
public void onDashBoardItemClick(String pos) {
Bundle bundle = new Bundle();
bundle.putString("TABVALUE", pos);
Intent intent = new Intent(getApplicationContext(),
DynamicTabsActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
private class AddButtonClick implements View.OnClickListener {
#Override
public void onClick(View view) {
mPresenter.getDataFromURL(getApplicationContext(), "");
}
}
}
class adapter
public class CountryAdapter extends
RecyclerView.Adapter<CountryAdapter.MyViewHolder> {
private Context context;
private List<CountryRes> list = new ArrayList<>();
private List<CountryRes> list_edit = new ArrayList<>();
private RecyclerItemClickListener onRecyclerItemClickListener;
public CountryAdapter(Context context, List<CountryRes> list,
RecyclerItemClickListener onRecyclerItemClickListener) {
this.context = context;
this.list = list;
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
}
#Override
public CountryAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View layoutView;
layoutView =
LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent,
false);
return new FooterViewHolder(layoutView,
onRecyclerItemClickListener);
}
#Override
public void onBindViewHolder(CountryAdapter.MyViewHolder holder, int
position) {
holder.tvCountryName.setText(list.get(position).getName());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvCountryName;
LinearLayout llListItem;
public MyViewHolder(View itemView) {
super(itemView);
tvCountryName = (TextView)
itemView.findViewById(R.id.tv_country_name);
llListItem = (LinearLayout)
itemView.findViewById(R.id.llListItem);
}
}
private class FooterViewHolder extends MyViewHolder {
public FooterViewHolder(View layoutView, final
RecyclerItemClickListener onRecyclerItemClickListener) {
super(layoutView);
llListItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onRecyclerItemClickListener != null) {
onRecyclerItemClickListener.onDashBoardItemClick(tvCountryName.getText().toS
tring());
}
}
});
}
}
}
Interface
public interface RecyclerItemClickListener {
void onDashBoardItemClick(String pos);
}
Case 1: Inside ViewHolder if you need to understand exactly position of clicked item you could call getAdapterPosition().
Case 2: You just need to receive all items of adapter. It is simple, make getter method which will return the items.
Case 3: Send info to activity, first make some specific event listener of your view inside ViewHolder, then event triggers (user clicks or other) and you call your interface method which you passed inside adapter, that was implemented in activity.
Tell me if you need an example, i will do it.
Try this one,
Button button= (Button) findViewById(R.id.your_button_id);
button.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View v) {
//create new ArrayList.
//ArrayList<CountryRes> showList=new ArrayList<>;
//now, put all stored data of a list in this arraylist.
showList.addAll(allCountriesData);
}
});
I have this method in my activity (CreatePhotostoryActivity):
#Override
public void showEditField(Moment oldMoment, final int index){
listRecycler.setVisibility(View.GONE);
editCaption.setVisibility(View.VISIBLE);
saveCancelNavbar.setVisibility(View.VISIBLE);
momentView.setVisibility(View.GONE);
photoStoryNavbar.setVisibility(View.GONE);
header.setVisibility(View.GONE);
Picasso.with(getApplicationContext()).load(oldMoment.photoUri).into(displayPhoto);
imageCaption.setText("");
imageCaption.setText(oldMoment.caption);
backIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
closeEditMoment();
}
});
saveText.setText("Save Moment");
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateMoment(imageCaption.getText().toString(), index);
Intent i = new Intent(CreatePhotostoryActivity.this, RVAdapter.class);
i.putExtra("isSaved", true);
startActivity(i);
}
});
cancelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
closeEditMoment();
Intent i = new Intent(CreatePhotostoryActivity.this, RVAdapter.class);
i.putExtra("isSaved", false);
startActivity(i);
}
});
}
In my RecyclerView adapter, showEditField is called using an interface, and it does work except that I am unable to detect whether saveButton or cancelButton was clicked. This is how it's called in the onBindViewHolder method of my RecyclerView adapter (RVAdapter):
((RecyclerView.ViewHolder) momentViewHolder).itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mAdapterCallback.showEditField(moments.get(position), position);
Intent intent = ((CreatePhotostoryActivity) mContext).getIntent();
Boolean isSaved = intent.getExtras().getBoolean("isSaved");
if (isSaved) {
holder.momentCaption.setText(moments.get(position).caption);
holder.momentPlaceholder.setVisibility(View.GONE);
holder.momentCaption.setVisibility(View.VISIBLE);
} else {
holder.momentPlaceholder.setVisibility(View.VISIBLE);
holder.momentCaption.setVisibility(View.GONE);
}
notifyDataSetChanged();
});
Do note my attempt of using an intent to find out which button was clicked. It doesn't work. momentCaption remains gone and momentPlaceHolder remains visible even though saveButton was clicked. The app also crashes afterwards.
Edit: I think calling this mAdapterCallback.showEditField(moments.get(position), position); before setting the values of momentCaption and momentPlaceholder is problematic, since showEditField calls other methods (e.g. closeEditMoment() before the intent is retrieved from the adapter.
Create an interface with two methods like saveBtnClick() and cancelBtnClick().
Implement the interface in your Activity.
Implement Click listener for both the buttons in the ViewHolder of your RecyclerView and call the Appropriate methods using Inteface's Object.
//Interface
public interface ManageButtonClicks
{
void saveBtnClick();
}
//Activity
public class MainActivity extends AppCompactActivity implements ManageButtonClicks
{
ManageButtonClicks manageButtonClicks=this;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mainactivity);
//Do the operations
adapter = new MyAdapter(this,adapterList,manageButtonClicks);
recyclerView.setAdapter(adapter);
}
void saveBtnClick()
{
Toast.makeText(this,"Clicked",Toast.LENGTH_SHORT).show();
}
}
//Adapter Class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>
{
ManageButtonClicks manageButtonClicks;
public MyAdapter(Context context, List< ModelClass > data, ManageButtonClicks manageButtonClicks)
{
inflater = LayoutInflater.from(context);
this.mDataList = data;
this.ctx = context;
util = new Util(ctx);
this.manageButtonClicks = manageButtonClicks;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
ViewGroup nonPrimeRow = (ViewGroup) inflater.inflate(R.layout.rowlayout, parent, false);
MyViewHolder_NON_PRIME holderNonPrime = new MyViewHolder_NON_PRIME(nonPrimeRow);
return holderNonPrime;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position)
{
ModelClass current = mDataList.get(position);
MyViewHolder_NON_PRIME holder_not_prime = (MyViewHolder_NON_PRIME) holder;
holder_not_prime.setdata(current);
}
class MyViewHolder extends RecyclerView.ViewHolder
{
public MyViewHolder(View itemView)
{
super(itemView);
}
}
public class MyViewHolder_NON_PRIME extends MyViewHolder
{
private Button btnSave;
public MyViewHolder_NON_PRIME(View view)
{
super(view);
btnSave = (MonteButton) view.findViewById(R.id.btnSave);
}
public void setdata(final ModelClass current)
{
btnSave.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
manageButtonClicks.saveBtnClick();
}
});
}
}
You have a global variable inside recyclerView adapter:
RecyclerViewAdapter {
private boolean isSaveButtonClicked = false;
private boolean isCancelButtonClicked = false;
public void saveButtonClicked(){
isSaveButtonClicked = true;
}}
public void cancelButtonClicked(){
isCancelButtonClicked = true;
}}
When your activity call onclickListeners , you will notice your adapter.
CreatePhotostoryActivity(){
private RecyclerView adapter;
onSaveButtonClicked(){
adapter.saveButtonClicked();
}
onCancelButtonClicked(){
adapter.cancelButtonClicked();
}
}
i made a onClickListener for my recyclerView but it just didn't work.
When i click an item from the recyclerView the log doesnt appear, the commands i put in the OnClickListener arent called ,i spend already 2-3 days to find the problem but i didn't see something wrong in my code it should cost the problem, probably its a small stupid mistake
but pls if anyone can help me get the problem i will be very happy.
In my adapter class i assigned the onClick to check and uncheck a checkbox
and in the MainActivity i assigned to save it in the dataBase
this is in my main activity
private void setUpGUI() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
cardView = (CardView) findViewById(R.id.cardView);
recyclerView = (RecyclerView) findViewById(R.id.recylerView);
adapter = new ItemAdapter(new ItemAdapter.ItemClickListener() {
#Override
public void onItemClicked(TodoItem item) {
Log.d(TAG, "on item click");
Uri uri = Uri.parse(TodoItemsContentProvider.CONTENT_URI + "/" + item.getId());
getContentResolver().update(uri, item.toContentValues(), null, null);
}
});
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showAddItemPopup();
}
});
this is my adapter class
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private static final String TAG = "item adapter";
private List<TodoItem> items = new ArrayList<>();
private ItemClickListener itemClickListener;
public ItemAdapter(ItemClickListener listener) {
itemClickListener = listener;
}
public void addItem(TodoItem item) {
if (!items.contains(item)) {
items.add(item);
Collections.sort(items);
notifyItemInserted(items.indexOf(item));
}
}
public void addItems(Collection<TodoItem> newItems) {
for (TodoItem item : newItems) {
if (!items.contains(item)) {
items.add(item);
}
}
Collections.sort(items);
notifyDataSetChanged();
}
public TodoItem getItem(int position) {
return items.get(position);
}
public void removeItem(int position) {
items.remove(position);
notifyItemRemoved(position);
}
// This listener listens for clicks to the viewholder. The viewholder passes back the position it is.
private final ClickListener clickListener = new ClickListener() {
#Override
public void onItemClicked(int position) {
Log.d(TAG, "on click adapter");
// Get the item that was clicked
TodoItem item = items.get(position);
// Set the completed state
item.setCompleted(!item.isCompleted());
//Update the UI
notifyItemChanged(position);
// Pass the item back the the itemclicklistener
itemClickListener.onItemClicked(item);
}
};
#Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.todo_list_item, parent, false);
return new ViewHolder(v, clickListener);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
TodoItem item = items.get(position);
holder.textView.setText(item.getText());
holder.subTextViewA.setText(item.getSubText());
holder.checkBox.setChecked(item.isCompleted());
//holder.backgroundLayout.setBackgroundColor(Color.parseColor("#ec48e418"));
}
#Override
public int getItemCount() {
return items.size();
}
// The view holder listens to clicks on the
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// private RelativeLayout backgroundLayout;
final TextView textView, subTextViewA;
final CheckBox checkBox;
final ClickListener clickListener;
public ViewHolder(View itemView, ClickListener clickListener) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textView);
subTextViewA = (TextView) itemView.findViewById(R.id.subTextViewA);
checkBox = (CheckBox) itemView.findViewById(R.id.checkBox);
//backgroundLayout = (RelativeLayout) itemView.findViewById(R.id.backgroundLayout);
itemView.setOnClickListener(this);
this.clickListener = clickListener;
}
#Override
public void onClick(View v) {
clickListener.onItemClicked(getAdapterPosition());
}
}
// Private listener fot the adapter to know about view clicks
private interface ClickListener {
void onItemClicked(int position);
}
// Public listener to pass the item back to the activity
public interface ItemClickListener {
void onItemClicked(TodoItem item);
}
}
When you click on your checkox, itemView.OnClickListener does not invoke. http://screencast.com/t/moP30Lfc49X
You can set click listener for checkbox and save (or remove) items from database like that http://screencast.com/t/Iw1K3Ld8nna
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(item, holder.checkBox.isChecked());
}
});
public interface OnItemClickListener {
void onItemClick(MainActivity.Item item, boolean save);
}
In your activity:
adapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
#Override
public void onItemClick(Item item, boolean save) {
if (save) {
// Save
} else {
// Remove from db
}
}
});
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");
}
});