RecyclerView在onCreateViewHolder上设置onclick事件,而不是onBindViewHolder

时间:2015-10-27 07:22:49

标签: android onclick android-recyclerview recycler-adapter

我对Android很陌生,在这里面临一个问题。

我最近在我的一个名为activity_drinks_menu的活动中切换到使用recycleler view而不是listview来显示饮料菜单。

应该发生的是:

我点击其中一个项目(点击了holder.layout),它应该"展开"显示更多与之相关的选项。我可以按下这些选项列表中的一个选项。当我这样做时,会出现一个弹出窗口(activityforresult),我新选择的选项会反映到我的Drinks对象中。选项列表仍在扩展"如果我想为该特定项目编辑更多选项。

一切正常,直到我看到弹出窗口(activityforresult),从活动中获取结果,将其反映到Drinks对象。在更新了这个Drinks对象之后,如上所述,选项列表必须仍然是"展开",显示我可以调整的所有选项。但是,它会被关闭"。

我猜这是因为我的代码编写方式,但无法找到解决此问题的绝佳方法。这是我的代码:

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();
        }
    }

如代码所示,我需要获取有关项目位置的信息,以便在我的下拉列表中显示正确的选项。因此,我的onCreateViewHolder方法中不能setOnClickEvents,因为我无法知道它的位置。

但是后来因为我正在重置&#34;每次ViewHolder对象绑定到itemView时我的onClickEvents,我认为这个错误正在发生。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:0)

这是我用来从

启用onclick的自定义类

在您的活动中

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);
                }
            }));

触摸处理的自定义类

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) {

        }
    }

处理点击的界面

public interface ClickListener {
    void OnClick(View view, int position);
}