I am having two fragments side by side in on the MainActivity
LeftFragment has a RecyclerView with colors and I want to set the background color and text on the Right Fragment when tap on any color on the LeftFragment
The app is crashing with the error null object reference error.
Here is my Github Repo. However, adding some code for reference.
Left Fragment
public class LeftFragment extends Fragment {
public LeftFragment() {
// Required empty public constructor
}
public static LeftFragment newInstance() {
return new LeftFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_left, container, false);
// private OnColorChooseListener mOnColorChooseListener;
ArrayList<Color> mColor = new ArrayList<>();
mColor.add(new Color(getResources().getColor(R.color.colorRed), getResources().getString(R.string.red)));
mColor.add(new Color(getResources().getColor(R.color.colorOrange), getResources().getString(R.string.orange)));
mColor.add(new Color(getResources().getColor(R.color.colorYellow), getResources().getString(R.string.yellow)));
mColor.add(new Color(getResources().getColor(R.color.colorLime), getResources().getString(R.string.lime)));
mColor.add(new Color(getResources().getColor(R.color.colorGreen), getResources().getString(R.string.green)));
mColor.add(new Color(getResources().getColor(R.color.colorCyan), getResources().getString(R.string.cyan)));
mColor.add(new Color(getResources().getColor(R.color.colorBlue), getResources().getString(R.string.blue)));
mColor.add(new Color(getResources().getColor(R.color.colorIndigo), getResources().getString(R.string.indigo)));
mColor.add(new Color(getResources().getColor(R.color.colorViolet), getResources().getString(R.string.violet)));
RecyclerView mRecyclerView = view.findViewById(R.id.color_list_view);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
RecyclerView.Adapter mAdapter = new ColorAdapter(mColor, getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
return view;
}
}
Right Fragment
public class RightFragment extends Fragment {
ColorAdapter colorAdapter;
ArrayList<Color> color;
public RightFragment() {
// Required empty public constructor
}
public static RightFragment newInstance() {
return new RightFragment();
}
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_right, container, false);
final ConstraintLayout constraintLayout = view.findViewById(R.id.right_color_block);
final TextView textView = view.findViewById(R.id.right_color_text);
colorAdapter.SetItemClickListener(new ColorAdapter.OnItemClickListener() {
#Override
public void OnItemClick(int position) {
constraintLayout.setBackgroundColor(color.get(position).getmColor());
textView.setText(color.get(position).getmLabel());
}
});
return view;
}
}
ColorAdaptor (RecyclerView)
public class ColorAdapter extends RecyclerView.Adapter<ColorAdapter.ColorViewHolder> {
private List<Color> mColor;
private Context mContext;
private OnItemClickListener mOnItemClickListener;
public ColorAdapter(List<Color> mColor, Context mContext) {
this.mColor = mColor;
this.mContext = mContext;
}
public void SetItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
#NonNull
#Override
public ColorViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.color_list_item, viewGroup, false);
return new ColorViewHolder(view, mOnItemClickListener);
}
#Override
public void onBindViewHolder(#NonNull final ColorViewHolder colorViewHolder, final int i) {
final Color color = mColor.get(i);
colorViewHolder.itemColorText.setText(color.getmLabel());
colorViewHolder.itemColorText.setBackgroundColor(color.getmColor());
colorViewHolder.itemColorText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext, "Item clicked: " + i, Toast.LENGTH_SHORT).show();
// colorViewHolder.feedbackBlock.setBackgroundColor(color.getmColor());
colorViewHolder.feedbackText.setText(color.getmLabel());
}
});
}
#Override
public int getItemCount() {
return mColor.size();
}
public interface OnItemClickListener {
void OnItemClick(int position);
}
class ColorViewHolder extends RecyclerView.ViewHolder {
public ConstraintLayout itemColorBlock;
public TextView itemColorText;
public ConstraintLayout feedbackBlock;
public TextView feedbackText;
public ColorViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
itemColorBlock = itemView.findViewById(R.id.color_block);
itemColorText = itemView.findViewById(R.id.color_text);
feedbackBlock = itemView.findViewById(R.id.right_color_block);
feedbackText = itemView.findViewById(R.id.right_color_text);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.OnItemClick(position);
}
}
}
});
}
}
}
Color
public class Color {
private int mColor;
private String mLabel;
public Color(#ColorInt int color, String label) {
this.mColor = color;
this.mLabel = label;
}
public String getmLabel() {
return mLabel;
}
public void setmLabel(String mLabel) {
this.mLabel = mLabel;
}
public int getmColor() {
return mColor;
}
public void setmColor(#ColorInt int mColor) {
this.mColor = mColor;
}
#NonNull
#Override
public String toString() {
return super.toString();
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LeftFragment leftFragment = LeftFragment.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.left_container, leftFragment).commit();
RightFragment rightFragment = RightFragment.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.right_container, rightFragment).commit();
}
}
Your App Crash on RightFragment.class because you are calling colorAdapter.SetItemClickListener (on line 43) as in **RightFragment colorAdapteris null **, you are setting adapter on the different fragment and implementing a listener on different so that's why this crash happens.
You can apply this listener on LeftFragment (where you originally set adapter) and on click of that(in listener callback) you can open right fragment ( send selected data from LeftFragment to RightFragment), This SO Answer can help you in this , when right fragment open you will get selected color data and here you can use it on RightFragment.
Related
I have a nested recyclerview to show the list of foods in each category. When the user clicks the increase or decrease button, the quantity will be updated to the quantity textview and synced to the cart stored in the database, but currently I don't know how to listen for the event when the user clicks these buttons.
Here is my current UI when run:
enter image description here
Here is my fragment:
public class TabOrderFragment extends Fragment {
private static final String ARG_RESTAURANT_ID = "restaurantId";
private int restaurantId;
View view;
RecyclerView menuRecyclerView;
RecyclerView.LayoutManager layoutManager;
ArrayList<Menu> menuArrayList;
MenuAdapter menuAdapter;
public TabOrderFragment() { }
public static TabOrderFragment newInstance(int restaurantId) {
TabOrderFragment fragment = new TabOrderFragment();
Bundle args = new Bundle();
args.putInt(ARG_RESTAURANT_ID, restaurantId);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
restaurantId = getArguments().getInt(ARG_RESTAURANT_ID);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tab_order, container, false);
if(restaurantId != 0) {
DatabaseHandler databaseHandler = DatabaseHandler.getInstance(getActivity());
menuArrayList = new ArrayList<Menu>();
menuArrayList = databaseHandler.getAllMenuFoodsByIdRestaurant(restaurantId);
menuRecyclerView = view.findViewById(R.id.rcv_foods_menu);
menuAdapter = new MenuAdapter(getActivity().getApplicationContext(), restaurantId);
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
menuRecyclerView.setLayoutManager(layoutManager);
menuAdapter.setData(menuArrayList);
menuRecyclerView.setAdapter(menuAdapter);
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d("TabOrderFragment", "Restaurant Id = " + restaurantId);
}
Here is my MenuAdapter:
public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuViewHolder> {
Context context;
private int restaurantId;
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
ArrayList<Menu> menuList;
public MenuAdapter(ArrayList<Menu> menuList) {
this.menuList = menuList;
}
public MenuAdapter(Context context, int restaurantId) {
this.context = context;
this.restaurantId = restaurantId;
}
public void setData(ArrayList<Menu> menuList) {
this.menuList = menuList;
notifyDataSetChanged();
}
#NonNull
#Override
public MenuViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_foods_menu, parent, false);
return new MenuViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MenuViewHolder holder, int position) {
Menu menu = menuList.get(position);
holder.txtMenuTitle.setText(menu.getTitle().concat(" (" + String.valueOf(menu.getQuantity()) + ")"));
LinearLayoutManager layoutManager = new LinearLayoutManager(holder.rcvListFoods.getContext(), LinearLayoutManager.VERTICAL, false);
layoutManager.setInitialPrefetchItemCount(menu.getFoods().size());
FoodAdapter foodAdapter = new FoodAdapter(menu.getFoods(), restaurantId);
holder.rcvListFoods.setLayoutManager(layoutManager);
holder.rcvListFoods.setAdapter(foodAdapter);
holder.rcvListFoods.setRecycledViewPool(viewPool);
}
#Override
public int getItemCount() {
if(menuList != null) {
return menuList.size();
}
return 0;
}
public class MenuViewHolder extends RecyclerView.ViewHolder {
private TextView txtMenuTitle;
private RecyclerView rcvListFoods;
public MenuViewHolder(#NonNull View itemView) {
super(itemView);
txtMenuTitle = itemView.findViewById(R.id.txv_menu_title);
rcvListFoods = itemView.findViewById(R.id.rcv_list_foods);
}
}
}
Here is my FoodAdapter:
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
private ArrayList<Food> foodList;
private int restaurantId;
private int userId;
SharedPreferences sharedPreferences;
public FoodAdapter(ArrayList<Food> foodList, int restaurantId) {
this.foodList = foodList;
this.restaurantId = restaurantId;
}
#NonNull
#Override
public FoodViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
sharedPreferences = fragmentActivity.getSharedPreferences("currentUser", Context.MODE_PRIVATE);
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_food, parent, false);
return new FoodViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull FoodViewHolder holder, int position) {
Food food =foodList.get(position);
Picasso.get().load(food.getThumbImage()).into(holder.foodThumbImage);
holder.foodName.setText(food.getName());
holder.foodDescription.setText(food.getDescription());
double price = Double.parseDouble(food.getPrice());
DecimalFormat formatter = new DecimalFormat("#,###");
holder.foodPrice.setText(formatter.format(price) + "đ");
}
#Override
public int getItemCount() {
if(foodList != null) {
return foodList.size();
}
return 0;
}
public class FoodViewHolder extends RecyclerView.ViewHolder {
private ImageView foodThumbImage;
private TextView foodName;
private TextView foodDescription;
private TextView foodPrice;
private TextView quantity;
private MaterialButton increaseBtn;
private MaterialButton decreaseBtn;
private ItemClickListener itemClickListener;
public FoodViewHolder(#NonNull View itemView) {
super(itemView);
foodThumbImage = itemView.findViewById(R.id.image_food);
foodName = itemView.findViewById(R.id.txv_food_name);
foodDescription = itemView.findViewById(R.id.txv_food_description);
foodPrice = itemView.findViewById(R.id.txv_food_price);
quantity = itemView.findViewById(R.id.txv_quantity);
increaseBtn = itemView.findViewById(R.id.btn_increase);
decreaseBtn = itemView.findViewById(R.id.btn_decrease);
}
}
in your food adapter's onBindViewHolder method use
holder.increaseBtn.setOnClickListener{
onIncreaseClick()
}
while create an interface like
interface Listener{
public void onIncreaseClick();
public void onDecreaseClick();
}
and implement your interface in your activity or fragment or viewmodel where you can listen for the click event
What you can do generally when you have something like that, is to create an interface for the interaction with the Recycler view:
interface Interaction {
public void onFoodClick(Food food)
}
Then you add an instance of this interface in your recycler view adapter, and you let your activity or fragment implement this interface, please find a good explanation here: https://stackoverflow.com/a/31671289/7334951
I'm having a problem with assigning onclicklistener to recyclerview items.
When I click the item, first click is ignored and listener doesn't run.
I mean, I have to click once, and then again to run the listener.
Once it runs, listener works well.
here is my code.
public class BoardFragment extends Fragment {
//recycler view ingredient
private RecyclerView recyclerView_board;
public static board_adapter mboard_adapter;
public static ArrayList<board_item> board_itemList;
private RecyclerView.LayoutManager board_LayoutManager;
//recycler view ingredient end
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(fragment_board, container, false);
//recycler view setting
recyclerView_board = (RecyclerView) v.findViewById(R.id.board_recycler);
board_itemList = new ArrayList<board_item>();
board_LayoutManager = new LinearLayoutManager(getActivity());
mboard_adapter = new board_adapter(board_itemList);
recyclerView_board.setAdapter(mboard_adapter);
recyclerView_board.setLayoutManager(board_LayoutManager);
recyclerView_board.setItemAnimator(new DefaultItemAnimator());
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView_board.getContext(), DividerItemDecoration.VERTICAL);
recyclerView_board.addItemDecoration(dividerItemDecoration);
board_item item = new board_item();
item.setName("Hello");
board_itemList.add(item);
mboard_adapter.notifyDataSetChanged();
//recycler view setting end
return v;
}
public static class board_item {
private String name;
private CheckBox button;
private int state = 0;
public String getName() {
return this.name;
}
public CheckBox getButton() {
return this.button;
}
public int getState() {
return this.state;
}
public void setName(String name) {
this.name = name;
}
public void setButton(CheckBox button) {
this.button = button;
}
public void setState(int state) {
this.state = state;
}
}
public class board_adapter extends RecyclerView.Adapter<board_adapter.ViewHolder> {
private ArrayList<board_item> temp_board_array;
public board_adapter(ArrayList<board_item> board_itemList) {
temp_board_array = board_itemList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_board, parent, false);
view.setOnClickListener(new board_onclick_listener());
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final int itemposition = position;
holder.board_name_text.setText(temp_board_array.get(position).getName());
class board_button_onclick_listener implements View.OnClickListener {
#Override
public void onClick(final View view) {
board_item item = board_itemList.get(itemposition);
Toast.makeText(view.getContext(), "button clicked", Toast.LENGTH_LONG).show();
if(item.getState() == 0){
}
else {
}
}
}
holder.board_favorite_button.setOnClickListener(new board_button_onclick_listener());
}
#Override
public int getItemCount() {
return temp_board_array.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView board_name_text;
public CheckBox board_favorite_button;
public ViewHolder(View itemView) {
super(itemView);
board_name_text = (TextView) itemView.findViewById(R.id.board_name);
board_favorite_button = (CheckBox) itemView.findViewById(R.id.board_favorite_button);
}
}
//각 아이템에 적용될 리스너
class board_onclick_listener implements View.OnClickListener {
#Override
public void onClick(final View view) {
int itemposition = recyclerView_board.getChildLayoutPosition(view);
board_item item = board_itemList.get(itemposition);
Toast.makeText(view.getContext(), item.getName() + " selected", Toast.LENGTH_LONG).show();
Intent intent = new Intent(view.getContext(), CardActivity.class);
view.getContext().startActivity(intent);
}
}
}
}
I tried to set the adapter on fragment, but nothing shows up.
The object retrieves the data from API but doesn't show on the screen.
I have already put the break point on rvItem.setAdapter(mainAdapter); but nothings happen, the debug passes straight through.
public class ItemFragment extends Fragment {
private MainAdapter mainAdapter;
private ItemPresenter itemPresenter;
private GridLayoutManager mLayoutManager;
private List<ObjectAdapter> list = new ArrayList<>();
private String region = "br";
#Bind(R.id.rvItem)
RecyclerView rvItem;
public ItemFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_item, container, false);
ButterKnife.bind(this, view);
itemPresenter = new ItemPresenter();
mLayoutManager = new GridLayoutManager(getActivity(), 4);
rvItem.setLayoutManager(mLayoutManager);
getList();
return view;
}
private void getList() {
itemPresenter.loadItemList(region, "all", AppConfigs.api_key, new ItemListListener() {
#Override
public void onRequestStarted() {
}
#Override
public void onRequestFinished() {
}
#Override
public void onError(Throwable error) {
}
#Override
public void onItemListLoad(List<ItemDto> itemList) {
displayItemList(ObjectAdapter.convertItemToObjetct(itemList));
}
});
}
public void displayItemList(List<ObjectAdapter> itemList) {
list = itemList;
mainAdapter = new MainAdapter(getActivity(), list, new MainAdapter.OnObjectClickListener() {
#Override
public void OnObjectClickListener(ObjectAdapter objectAdapter) {
Toast.makeText(getActivity(), "Object Adapter" + objectAdapter.Id, Toast.LENGTH_SHORT).show();
}
});
rvItem.setAdapter(mainAdapter);
mainAdapter.notifyDataSetChanged();
}
}
Adapter:
public class MainAdapter extends
RecyclerView.Adapter<MainAdapter.MainAdapterViewHolder> {
public List<ObjectAdapter> mObjecterList;
private final OnObjectClickListener listener;
private Context mContext;
public interface OnObjectClickListener {
void OnObjectClickListener(ObjectAdapter objectAdapter);
}
public MainAdapter(Context context, List<ObjectAdapter> objectAdapterList, OnObjectClickListener listener) {
this.mObjecterList = objectAdapterList;
this.listener = listener;
this.mContext = context;
}
#Override
public MainAdapter.MainAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_main_adapter, parent, false);
return new MainAdapterViewHolder(view);
}
#Override
public void onBindViewHolder(MainAdapter.MainAdapterViewHolder holder, int position) {
ObjectAdapter ob = mObjecterList.get(position);
holder.tvNameText.setText(ob.Name);
holder.bind(mObjecterList.get(position), listener);
String url = "";
switch (ob.Type){
case CHAMPION: url = String.format(AppConfigs.portraitChampion, ob.Portrait);
break;
case SPELL: url = String.format(AppConfigs.portraitSpell, ob.Portrait);
break;
case ITEM: url = String.format(AppConfigs.portraitItem, ob.Portrait);
break;
}
Picasso.with(mContext).load(url).into(holder.ivRetrato);
}
#Override
public int getItemCount() {
return this.mObjecterList.size();
}
public static class MainAdapterViewHolder extends RecyclerView.ViewHolder {
public TextView tvNameText;
public ImageView ivRetrato;
public MainAdapterViewHolder(View itemView) {
super(itemView);
this.tvNameText = (TextView) itemView.findViewById(R.id.tvNameText);
this.ivRetrato = (ImageView) itemView.findViewById(R.id.ivImagePortrait);
}
public void bind(final ObjectAdapter objectAdapterListItem, final OnObjectClickListener listener) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.OnObjectClickListener(objectAdapterListItem);
}
});
}
}
}
You need to set adapter directly at onCreateView method and call notifyDataSetChanged() of adapter when data loaded
I would like to know how to handle position of the row if the adapter is changed - for example if I write something to SearchView - adapter has changed and position is different. I have done this (below), but it shows the item before changed position.
My issue is with Recycler view item click.
Could you help me with that?
Adapter
public class ContactsRecyclerAdapter extends RecyclerView.Adapter<ContactsRecyclerAdapter.BindingHolder> {
private static OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
private List<Contact> mContacts;
private List<Contact> mContactsFiltered;
SearchViewFilter filter;
Context mContext;
public ContactsRecyclerAdapter(Context context, List<Contact> contact) {
this.mContext = context;
this.mContacts = contact;
this.mContactsFiltered = contact;
filter = new SearchViewFilter(mContacts, this);
}
public static class BindingHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public BindingHolder(final View rowView) {
super(rowView);
binding = DataBindingUtil.bind(rowView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
public ViewDataBinding getBinding() {
return binding;
}
}
#Override
public BindingHolder onCreateViewHolder(ViewGroup parent, int type) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_contact, parent, false);
BindingHolder holder = new BindingHolder(view);
return holder;
}
#Override
public void onBindViewHolder(BindingHolder holder, int position) {
final Contact contact = mContactsFiltered.get(position);
holder.getBinding().setVariable(BR.contact, contact);
holder.getBinding().executePendingBindings();
}
Fragment
public class ContactListFragment extends Fragment implements View.OnClickListener {
FloatingActionButton fabButton;
SearchView searchView;
RecyclerView recyclerView;
String name, number, email;
private List<Contact> mContact = new ArrayList<>();
private ContactsRecyclerAdapter mAdapter;
public static ContactListFragment newInstance() {
Bundle args = new Bundle();
ContactListFragment fragment = new ContactListFragment();
fragment.setArguments(args);
return fragment;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contact_list, container, false);
searchView = (SearchView) view.findViewById(R.id.search_view);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mContact = SugarRecord.listAll(Contact.class);
mAdapter = new ContactsRecyclerAdapter(getActivity(), mContact);
recyclerView.setAdapter(mAdapter);
//item click
mAdapter.setOnItemClickListener(new ContactsRecyclerAdapter.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
Contact contact = SugarRecord.findById(Contact.class, (long) position + 1);
name = contact.getName();
number = contact.getNumber();
email = contact.getEmail();
showAlertDialog();
}
});
searchFilter();
return view;
}
public void sortList() {
if(mContact.size() > 0) {
if (!isSort) {
Collections.sort(mContact, new Comparator<Contact>() {
#Override
public int compare(Contact contact1, Contact contact2) {
return contact1.getName().compareToIgnoreCase(contact2.getName());
}
});
}
else {
Collections.reverse(mContact);
isSort = false;
}
}
mAdapter.notifyDataSetChanged();
Click listener does not work with a RecyclerView. use OnItemTouchListener()
RecyclerView recyclerView = findViewById(R.id.recycler);
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
#Override public void onItemClick(View view, int position) {
// do whatever
}
#Override public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
you have to overide onclick in BindingHolder class. Inside onclick method invoke a callback method of object passed via constructor etc
public static class BindingHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public BindingHolder(final View rowView) {
super(rowView);
binding = DataBindingUtil.bind(rowView);
public void onClick(View view) {
//call a callback method here
}
}
public ViewDataBinding getBinding() {
return binding;
}
}
I'm having the usual problem with a list + a RecyclerView: when I change the resource file of an item (aka: selected/unselected star icon) and then scroll, other items of the list are keeping the same selected/unselected state for their own star. Plus, when I select an item and then go back, I'm missing the selected/unselected state.
The fullStar and the emptyStar are simple Android Vector images.
Here it is my ListFragment:
public class PetrolStationListFragment extends Fragment {
private RecyclerView mPetrolStationRecyclerView;
private PetrolStationAdapter mAdapter;
private int itemPosition;
public static boolean toBeCreated;
private static final String ARG_POSITION = "position";
// Design pattern to instantiate a new fragment.
public static PetrolStationListFragment newInstance(int position) {
PetrolStationListFragment fragment = new PetrolStationListFragment();
Bundle args = new Bundle();
args.putInt(ARG_POSITION, position);
fragment.setArguments(args);
return fragment;
}
/********************************************************/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_petrol_station_list, container, false);
mPetrolStationRecyclerView = (RecyclerView) view.findViewById(R.id.petrol_recycler_view);
mPetrolStationRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
updateUI();
return view;
}
#Override
public void onResume() {
super.onResume();
updateUI();
}
private void updateUI() {
PetrolStationDAO petrolStationDAO = PetrolStationDAO.get(getActivity());
List<PetrolStation> petrolStations = petrolStationDAO.getPetrolStations();
if (mAdapter == null || toBeCreated) {
mAdapter = new PetrolStationAdapter(petrolStations);
mPetrolStationRecyclerView.setAdapter(mAdapter);
toBeCreated = false;
} else {
mAdapter.notifyItemChanged(itemPosition);
}
}
private class PetrolStationHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private PetrolStation mPetrolStation;
private TextView mNameTextView;
private TextView mAddressTextView;
private TextView mDistanceTextView;
private AppCompatImageView mStar;
private boolean mFavourite;
public PetrolStationHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mNameTextView = (TextView) itemView.findViewById(R.id.list_item_station_name_text_view);
mAddressTextView = (TextView) itemView.findViewById(R.id.list_item_station_address_text_view);
mDistanceTextView = (TextView) itemView.findViewById(R.id.list_item_station_distance_text_view);
mStar = (AppCompatImageView) itemView.findViewById(R.id.list_item_station_star_image_view);
mStar.setTag(R.id.list_item_station_star_image_view, "emptyStar");
}
public void bindPetrolStation(PetrolStation petrolStation) {
mPetrolStation = petrolStation;
mNameTextView.setText(mPetrolStation.getName());
mAddressTextView.setText("Via Verdi, 19/A");
mDistanceTextView.setText("300 meters");
mFavourite = mPetrolStation.isFavourite(mStar);
Log.d("FAVOURITE", "mFavourite: " + mFavourite);
//setStarByBoolean();
mStar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setStarByTag();
}
});
}
#Override
public void onClick(View v) {
//itemPosition = mPetrolStationRecyclerView.getChildAdapterPosition(v);
Intent intent = PetrolStationPagerActivity.newIntent(getActivity(), mPetrolStation.getId());
startActivity(intent);
}
public void setStarByBoolean() {
if (!mFavourite) {
mStar.setImageResource(R.drawable.ic_star_border_orange);
mStar.setTag(R.id.list_item_station_star_image_view, "emptyStar");
} else {
mStar.setImageResource(R.drawable.ic_star_orange);
mStar.setTag(R.id.list_item_station_star_image_view, "fullStar");
}
}
public void setStarByTag() {
if (mStar.getTag(R.id.list_item_station_star_image_view).equals("emptyStar")) {
mStar.setImageResource(R.drawable.ic_star_orange);
mStar.setTag(R.id.list_item_station_star_image_view, "fullStar");
} else {
mStar.setImageResource(R.drawable.ic_star_border_orange);
mStar.setTag(R.id.list_item_station_star_image_view, "emptyStar");
}
}
}
private class PetrolStationAdapter extends RecyclerView.Adapter<PetrolStationHolder> {
private List<PetrolStation> mPetrolStations;
public PetrolStationAdapter(List<PetrolStation> petrolStations) {
mPetrolStations = petrolStations;
}
#Override
public PetrolStationHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.list_item_petrol_station, parent, false);
return new PetrolStationHolder(view);
}
#Override
public void onBindViewHolder(PetrolStationHolder holder, int position) {
PetrolStation petrolStation = mPetrolStations.get(position);
Log.d("POSITION", "position: " + position);
holder.bindPetrolStation(petrolStation);
}
#Override
public int getItemCount() {
return mPetrolStations.size();
}
}
}
And here a the getter and the setter for the PetrolStation Model class:
public boolean isFavourite(AppCompatImageView star) {
if (star.getTag(R.id.list_item_station_star_image_view).equals("emptyStar")) {
mFavourite = false;
} else {
mFavourite = true;
}
return mFavourite;
}
public void setFavourite(boolean favourite) {
this.mFavourite = favourite;
}
Any hint about how to fix this issue? I'm finding difficult to apply the CheckBoxes examples I've found to my own case.