[英]RecyclerView setting onclick event at onCreateViewHolder, not onBindViewHolder
I'm pretty new to Android and is faced with a problem here. 我刚接触Android,在这里遇到了问题。
I have recently switched to using recycler view instead of listview in one of my activities named activity_drinks_menu
for displaying menus of drinks. 我最近在名为
activity_drinks_menu
一项活动中使用了回收站视图而不是列表视图来显示饮料菜单。
What is supposed to be happening is this: 应该发生的是这样的:
I click on one of the items (holder.layout is clicked), it should "expand" to show more options related to it. 我单击其中一项(单击holder.layout),它应“展开”以显示与其相关的更多选项。 I could press on one of the options in these list of options.
我可以按这些选项列表中的一个。 When I do so, a popup window (activityforresult) appears and the option that I newly chose gets reflected to my
Drinks
object. 这样做时,会出现一个弹出窗口(activityforresult),并且我新选择的选项会反映到我的
Drinks
对象中。 The options list is still "expanded" in case I want to edit more options for that specific item. 如果我想为该特定项目编辑更多选项,则选项列表仍处于“展开”状态。
Everything works fine until I see the popup window (activityforresult), get the result back from the activity, reflect it to the Drinks
object. 一切正常,直到我看到弹出窗口(activityforresult),从活动中获取结果,并将其反映到
Drinks
对象。 After this Drinks
object has been updated, as I have mentioned above, the options list MUST still be "expanded", showing all the options available for me to tweek with. 如上所述,在更新了
Drinks
对象之后,选项列表仍必须“展开”,显示到tweek可用的所有选项。 However, it gets "closed". 但是,它被“关闭”。
I am guessing this is because of the way how my code is written but could not figure out a brilliant way to resolve this problem. 我猜这是由于我的代码编写方式而无法找到解决此问题的绝妙方法。 Here's my code:
这是我的代码:
package com.bringit.bringitrecyclerviewtest;
import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import java.util.ArrayList;
/**
* Customized adapter for RecyclerView
*/
public class DrinkMenuItem extends RecyclerView.Adapter<DrinkMenuItem.ViewHolder> {
private Context context;
private ViewGroup parent;
private ArrayList<Drink> menu;
private ArrayList<DrinkSelected> selected;
private DrinkMenuBasketItem selectedAdapter;
private DrinkMenuDropdownItem dropdownAdapter;
public static class ViewHolder extends RecyclerView.ViewHolder {
public LinearLayout layout;
public TextView name, price;
public ListView dropdown;
public Button basket;
public boolean tabbed = false;
public ViewHolder(View itemView) {
super(itemView);
layout = (LinearLayout)itemView.findViewById(R.id.drink_menu_layout);
name = (TextView)itemView.findViewById(R.id.drink_menu_name);
price = (TextView)itemView.findViewById(R.id.drink_menu_price);
dropdown = (ListView)itemView.findViewById(R.id.drink_menu_dropdown_list);
basket = (Button)itemView.findViewById(R.id.drink_menu_basket_button);
}
}
public DrinkMenuItem(Context context, ArrayList<Drink> menu, ArrayList<DrinkSelected> selected, DrinkMenuBasketItem selectedAdapter) {
this.context = context;
this.menu = menu;
this.selected = selected;
this.selectedAdapter = selectedAdapter;
this.dropdownAdapter = null;
}
public void updateDropdown(int requestedOption, int responsedOptionitem) {
dropdownAdapter.updateSelectedOption(requestedOption, responsedOptionitem);
notifyDataSetChanged();
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
this.parent = parent;
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_drink_menu, parent, false);
return new ViewHolder(itemView);
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Drink d = menu.get(position);
holder.name.setText(d.getName());
holder.price.setText(d.getPrice() + d.totalAdditionalPrice() + "원");
setOnClickEvent(holder, position, parent);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return menu.size();
}
private void setOnClickEvent(final ViewHolder holder, final int position, final ViewGroup parent) {
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!holder.tabbed) {
//make dropdown
dropdownAdapter = new DrinkMenuDropdownItem(context, menu, position, holder.price);
holder.dropdown.setAdapter(dropdownAdapter);
setListViewHeight(holder.dropdown);
//set dropdown-related stuff
holder.tabbed = true;
holder.basket.setVisibility(View.VISIBLE);
((RecyclerView) parent).smoothScrollToPosition(position);
}
else {
Log.d("dropdown", "is this being called when options is changed? 1");
//delete dropdown
holder.dropdown.setAdapter(null);
menu.get(position).returnToUnselected();
holder.price.setText(menu.get(position).getPrice() + "원");
setListViewHeight(holder.dropdown);
//reset dropdown-related stuff
holder.tabbed = false;
holder.basket.setVisibility(View.GONE);
}
}
});
holder.basket.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Drink d = menu.get(position);
boolean doesExist = false; int i = 0;
//checking if already in the list
for(DrinkSelected ds : selected) {
//the same entry if the name and option are the same
if(ds.getName().equals(d.getName()) && ds.getOption().equals(d.printOptionForSelected())) {
doesExist = true;
i = selected.indexOf(ds);
break;
}
}
if(doesExist) {
selected.get(i).setCount(selected.get(i).getCount()+d.getCount());
selected.get(i).setPrice(selected.get(i).getPrice()+(d.getPrice()+d.totalAdditionalPrice()));
}
else {
selected.add(new DrinkSelected(d.getName(), d.getCount(), d.getPrice() + d.totalAdditionalPrice(), d.printOptionForSelected()));
}
selectedAdapter.notifyDataSetChanged();
holder.dropdown.setAdapter(null);
menu.get(position).returnToUnselected();
holder.price.setText(menu.get(position).getPrice() + "원");
setListViewHeight(holder.dropdown);
//set basket button gone
holder.basket.setVisibility(View.GONE);
}
});
}
private void setListViewHeight(final ListView l) {
ViewGroup.LayoutParams params = l.getLayoutParams();
if(l.getAdapter() == null) {
params.height = 0;
}
else {
int numberOfItems = l.getAdapter().getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = l.getAdapter().getView(itemPos, null, l);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = l.getDividerHeight() * (numberOfItems - 1);
// Set list height.
params.height = totalItemsHeight + totalDividersHeight;
}
l.setLayoutParams(params);
l.requestLayout();
}
}
As the code shows, I need to have the information about the position of the item in order to display the correct options in my dropdown list. 如代码所示,我需要具有有关项目位置的信息,以便在下拉列表中显示正确的选项。 Therefore, I cannot
setOnClickEvents
in my onCreateViewHolder method, because there is no way for me to know which position it is for. 因此,我无法在onCreateViewHolder方法中设置
setOnClickEvents
,因为无法让我知道它的位置。
But then because I am "resetting" my onClickEvents every time the ViewHolder object gets binded to the itemView, I think this error is occurring. 但是,因为每次ViewHolder对象绑定到itemView时,我都在“重置”我的onClickEvent,所以我认为此错误正在发生。 Could anyone help me out here?
有人可以帮我吗?
here is the custom class I use to enable onclick from 这是我用来启用onclick的自定义类
in your activity 在你的活动中
RecyclerView drawerList = (RecyclerView) findViewById(R.id.DrawerList);
drawerList.setLayoutManager(new LinearLayoutManager(this));
// pass context , implement click listener interface
drawerList.addOnItemTouchListener(new RecycleOntouchListener(Home.this, new ClickListener() {
@Override
public void OnClick(View view, int position) {
SelectItem(position);
}
}));
custom class to handle on touch 自定义类以处理触摸
public class RecycleOntouchListner implements RecyclerView.OnItemTouchListener {
private GestureDetector mGestureDetector;
private ClickListener mClickListner;
public RecycleOntouchListner(Context mContext, ClickListener clickListner) {
this.mClickListner = clickListner;
mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && mClickListner != null && mGestureDetector.onTouchEvent(e)) {
mClickListner.OnClick(child, rv.getChildAdapterPosition(child));
return false;
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
interface to handle click 处理点击的界面
public interface ClickListener {
void OnClick(View view, int position);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.