简体   繁体   English

RecyclerView在onCreateViewHolder而非onBindViewHolder处设置onclick事件

[英]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.

相关问题 RecyclerVIew onCreateViewHolder 和 onBindViewHolder 没有被调用 - RecyclerVIew onCreateViewHolder and onBindViewHolder is not called RecyclerView 同时为所有项目调用 onCreateViewHolder 和 onBindViewHolder - RecyclerView calling onCreateViewHolder and onBindViewHolder for all items at once 支持库和RecyclerView onBindViewHolder和onCreateViewHolder的Proguard问题 - Proguard issue with Support Library and RecyclerView onBindViewHolder and onCreateViewHolder Recyclerview 不调用任何 Adapter 方法:onCreateViewHolder、onBindViewHolder - Recyclerview not call any Adapter method: onCreateViewHolder, onBindViewHolder RecyclerView 适配器`onCreateViewHolder` &amp; `onBindViewHolder` 只调用一次 - RecyclerView adapter `onCreateViewHolder` & `onBindViewHolder` invoked only once RecyclerView中没有调用适配器的onCreateViewHolder和onBindViewHolder方法? - Adapter onCreateViewHolder and onBindViewHolder methods are not getting called in RecyclerView? Recyclerview 不调用任何适配器方法 :onCreateViewHolder,onBindViewHolder, - Recyclerview not call any Adapter method :onCreateViewHolder,onBindViewHolder, Recyclerview ViewHolder:onCreateViewHolder,视图绑定和onBindViewHolder在同一个类中 - Recyclerview ViewHolder : onCreateViewHolder , view binding and onBindViewHolder in the same class 在onCreateViewHolder和onBindViewHolder中进行实例化时,RecyclerView会花费很多时间:进度栏冻结 - RecyclerView taking a lot of time when instaceiating in onCreateViewHolder and onBindViewHolder: Progressbar freezes Recyclerview 不调用任何适配器方法:onBindViewHolder,onCreateViewHolder - Recyclerview doesnt call any Adapter method :onBindViewHolder,onCreateViewHolder
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM