Add a bottom menu for RecyclerView item - android-recyclerview

I have a recyclerview that will have an option button to the right, and I want to achieve something like the animation below:
I'm using this as my reference but I have some disconnects.
First I want to know if I can even do this because every thing I find on adding a menu to a recyclerview is adding a basic menu pop up, which is not what I want.
I also have some disconnect on accessing the menu from the viewholder, I can access it from my fragment but I'd think I'd need to call it from the viewholder so I have what row clicked to fire up the menu.
If I'm overthinking the implementation and there's a simpler approach, I'm open to hearing it.

Im not sure if I am understanding what you want, but if it is to have a button that exist in the row items of the recyclerview to pop up a drawer from the bottom of the screen whenever the button is clicked, then you should just use a normal drawer setup (Navigation Drawer, Create a navigation drawer) for the activity and have an OnClickListener added to the row buttons (which can be done in onCreateViewHolder() or the holder's constructor) that triggers the drawer to open by calling openDrawer(). Note to do the latter, you have to pass the navigation drawer (DrawerLayout) into the adapter via the adaptors constructor (which means your adapter needs something to store the DrawerLayout in).
So
public class CustomAdaptor extends RecyclerView.Adapter<CustomViewHolder>{
private Context mContext;
private int mLayoutResourceId;
private ArrayList<Item> items;
private DrawerLayout drawer;
public CustomAdaptor (Context context, int resource, ArrayList<Item> itemArray, DrawerLayout drawer) {
this.mContext = context;
this.mLayoutResourceId = resource;
this.items = itemArray;
this.drawer = drawer;
}
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(mLayoutResourceId, parent, false);
final CustomViewHolder holder = new CustomViewHolder(view);
holder.mbutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//Check if drawer is null and if not then call
drawer.drawerOpen();
}
});
return holder;
}
}
where mButton is the button in the holder/row. Note I havent tested this so there might be somethings im forgetting.

Related

change item color on click in recyclerview android

I am trying to change the color of the items on click when the action mode is active. The problem is that e.g if there are five items in a recyclerview and you click one, scroll down and select sixth item and destroy the action mode. The next time you start selecting, that sixth item has automatically changed its color without you selecting it. I don't know why it is happening.
public static List<ModelClass> items = new ArrayList<>();
boolean isSelectMode = false;
boolean isActionModeEnabled = false;
public static List<ModelClass> selectList = new ArrayList<>();
#Override
public void onBindViewHolder(#NonNull MyAdapter.MyViewHolder holder, int
position) {
holder.bind(items.get(position));
ModelClass modelClass = items.get(position);
if (modelClass.isChecked() && isActionModeEnabled){
holder.row.setBackgroundColor(Color.GREEN);
modelClass.setChecked(true);
} else {
holder.row.setBackgroundColor(Color.TRANSPARENT);
modelClass.setChecked(false);
}
}
public class MyViewHolder extends RecyclerView.ViewHolder{
public MyViewHolder(#NonNull View itemView) {
super(itemView);
row = itemView.findViewById(R.id.row);
public void bind(ModelClass model) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isActionModeEnabled) {
isSelectMode = true;
s = items.get(getAdapterPosition());
if (!selectList.contains(s)){
selectList.add(s);
row.setBackgroundColor(Color.GREEN);
model.setChecked(true);
} else {
selectList.remove(s);
row.setBackgroundColor(Color.TRANSPARENT);
model.setChecked(false);
}
}
});
}
The problem is going to be in your view holder binding:
if (modelClass.isChecked() && isActionModeEnabled){
holder.row.setBackgroundColor(Color.GREEN);
modelClass.setChecked(true);
} else {
holder.row.setBackgroundColor(Color.TRANSPARENT);
modelClass.setChecked(false);
}
Remember that view holders are reused. That means that they will retain their internal state unless you change them. Your item list will also remember its state. Make sure you cover all the possible states of the item list and the reused view holders in the code above: You are probably missing a combination.
I recommend that you set a break point in the code above to make sure it is doing what you want. It should become obvious to you once you take a closer look.

How to click a View which is visible behind a RecyclerView's invisible ViewHolder item?

I have a full screen RecyclerView which will have one invisible ViewHolder Item, like below
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
....
if (position == 6) {
viewHolder.itemView.setMinimumHeight(Resources.getSystem().getDisplayMetrics().heightPixels);
viewHolder.itemView.setVisibility(View.GONE);
viewHolder.setIsRecyclable(false);
}
...
}
Once the position 6 shows up on the screen, I can see the ImageView behind it and I'd like to be able to click on that. I have added an event handler to that ImageView but it is not being triggered. It seems RecyclerView is preventing the click event to bubble down. Is there any way to click a View thru invisible/gone RecyclerView ViewItem?
Since I asked the question, I have tried multiple techniques/methods which could/should pass the click/tap event down to the view hierarchy but nothing worked. The feature I was trying to build in the app was very complex and the app itself became very complicated overtime. Too many views on top of each other and global event handlers made the implementation harder.
So I have decided as last resort that to have an empty/transparent view holder in the RecyclerView which listens the click and touch events and based on the coordinates of the touch event, I fire different action. Here is the code:
private float[] lastTouchDownXY = new float[2];
public MyView getMyView(final Context context) {
MyView view = new MyView(context);
view.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
lastTouchDownXY[0] = motionEvent.getRawX();
lastTouchDownXY[1] = motionEvent.getRawY();
}
return false;
}
});
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final float x = lastTouchDownXY[0];
final float y = lastTouchDownXY[1];
int[] mLocButton = new int[2];
// mButton is the button in the background and visible thru transparent viewholder
mButton.getLocationOnScreen(mLocButton);
final int left = mLocButton[0];
final int top = mLocButton[1];
if (x > (left - mOffset) && x < (left + mOffset + mButtonWidth) &&
y > (top - mOffset) && y < (top + mOffset + mMuteUnmuteButtonHeight)) {
// mButton clicked
} else {
// entire view clicked except mButton clickable area
}
}
});
return view;
}

Prevent Android RecyclerView OnRemove shifting of remaining Items

After removing an item from a recyclerview, by default, the other items shift up to fill the space of the removed element. How do I stop this movement?
I want to leave a gap in the view after I remove an item, instead of the other items moving up to replace it.
How about not removing an item, but making its itemView invisible? You can just add two states to an object, that you use to bind ViewHolder, check this state in onBindViewHolder method and set visibility of an itemView with any animation you need. Something like this:
public class RecyclerViewItem {
public boolean isVisible;
}
Set required state in your Activity/Fragment:
private void removeItem(int position){
adapter.getDataSet().get(position).isVisible = false;
adapter.notifyItemChanged(position);
}
And in your RecyclerView.Adapter:
private ArrayList<RecyclerViewItem> mDataSet;
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
RecyclerViewItem item = mDataSet.get(position);
holder.itemView.setVisibility(item.isVisible? View.VISIBLE : View.INVISIBLE);
}

mistake with finish an activity in android

I have a main activity with 6 buttons. Every button starts a new activity.
The program worked well but after that I changed some graphical attributes and made some changes in the theme a mistake occurred . I should press back button 3 times to return from an activity or exit from the main activity. Any suggestions?
btn_weeks.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
Intent i = new Intent(MainActivity.this, Weeks.class);
startActivity(i);
return false;
}
});
Buttons should implements View.OnClickListener and not OnTouchListener.

define an event for custom android toast

I've made a custom android toast and tried to define on click listener event for the textview, but it doesn't work....any help??
LayoutInflater inflater = LayoutInflater.from(cntxt);
View layout = inflater.inflate(R.layout.toast_layout,null);
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText(msg);
Toast toast = new Toast(cntxt);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method s'tub
//didn't go here???
toast.cancel();
}
});
toast.show();
Unfortunately, a Toast and any child child views of a Toast cannot receive touch input. You will have to create a custom View that mimics a Toast and attach that View to a layout.