【问题标题】:How to do you implement a recyclerview onClick in a Fragment?如何在 Fragment 中实现 recyclerview onClick?
【发布时间】:2018-09-03 09:20:31
【问题描述】:

我的问题和这个类似。

Best approach to communicate between Fragment/Activity and RecyclerView.Adapter?

我知道当用户点击Fragment中的一个按钮时,如何在相应的Activity中实现一个onClickListener、一个Interface和一个OnItemSelected方法。我有一个带有数组列表的片段。通过单击片段中数组列表中的每个项目,ExoPlayer 将在新活动或片段中打开。据我了解,onItemClickListener 不适用于 Recyclerview。如何将 onClick 方法设置为列表中的项目?另外,我是否在 RecyclerView 之外设置 onClick?这是我的 RecyclerView 适配器类。接口是否应该采用额外的参数?先感谢您。

公共类 StepsAdapter 扩展 RecyclerView.Adapter {

private static final String TAG = StepsAdapter.class.getSimpleName();
private ArrayList<Steps> stepsList = new ArrayList<Steps>();
private StepsAdapter.StepsAdapterOnClickHandler mClickHandler;

/**
 * The interface that receives onClick messages.
 */
public interface StepsAdapterOnClickHandler {
    void onClick(Steps stepClick);
}

/**
 * Creates a StepsAdapter.
 *
 * @param clickHandler The on-click handler for this adapter. This single handler is called
 *                     when an item is clicked.
 */
public StepsAdapter(StepsAdapterOnClickHandler clickHandler,ArrayList<Steps> stepsList) {
    mClickHandler = clickHandler;
    this.stepsList = stepsList;
}

/**
 * Cache of the children views for a steps list item.
 */
public class StepsAdapterViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    @BindView(R.id.step_short_desc)
    public TextView stepShortDescription;

    @BindView(R.id.step_description)
    public TextView stepDescription;

    public StepsAdapterViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);
        view.setOnClickListener(this);
    }

    /**
     * This gets called by the child views during a click.
     *
     * @param v The View that was clicked
     */
    @Override
    public void onClick(View v) {
        int adapterPosition = getAdapterPosition();
        Steps stepClick = stepsList.get(adapterPosition);
        mClickHandler.onClick(stepClick);
    }
}

@Override
public StepsAdapter.StepsAdapterViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    Context context = viewGroup.getContext();
    int layoutIdForListItem = R.layout.steps_list_item;
    LayoutInflater inflater = LayoutInflater.from(context);
    boolean shouldAttachToParentImmediately = false;
    View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
    return new StepsAdapter.StepsAdapterViewHolder(view);
}

@Override
public void onBindViewHolder(StepsAdapter.StepsAdapterViewHolder holder, int position) {

    //Binding data
    final Steps stepsView = stepsList.get(position);

    holder.stepShortDescription.setText(stepsView.getStepShortDescription());
    holder.stepDescription.setText(stepsView.getStepDescription());
}

@Override
public int getItemCount() {
    return stepsList.size();
}

public void setStepsList(ArrayList<Steps> mStepsList) {
    this.stepsList = mStepsList;
    notifyDataSetChanged();
}

}

对应的片段。点击方法是否正确实现?

public class StepsListFragment extends Fragment implements StepsAdapter.StepsAdapterOnClickListener {

    // Tag for logging
    private final String TAG = StepsListFragment.class.getSimpleName();

    @BindView(R.id.recyclerview_steps)
    RecyclerView mRecyclerView;

    ArrayList<Steps> stepsArrayList;

    Recipes recipes;

    // Final Strings to store state information about the list of steps and list index
    public static final String STEPS_LIST_INDEX = "list_index";


    // Define a new interface OnStepsClickListener that triggers a callback in the host activity
    OnStepClickListener mCallback;

    // OnStepsClickListener interface, calls a method in the host activity named onStepSelected
    public interface OnStepClickListener {
        void onClick(Steps stepClick);
    }

    // Override onAttach to make sure that the container activity has implemented the callback
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

//        // This makes sure that the host activity has implemented the callback interface
//        // If not, it throws an exception
        try {
            mCallback = (OnStepClickListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement OnStepSelectedListener");
        }
    }

   /**
     * Mandatory empty constructor for the fragment manager to instantiate the fragment
     */
    public StepsListFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

//        //Inflate the Steps fragment layout
        View rootView = inflater.inflate(R.layout.fragment_steps, container, false);
//        // Bind the views
        ButterKnife.bind(this, rootView);

        Bundle bundle = this.getArguments();
        if (bundle != null) {
            recipes = getArguments().getParcelable("Recipes");

            stepsArrayList = new ArrayList<>();
            stepsArrayList = recipes.getRecipeSteps();
        }
        if (savedInstanceState != null) {
            //Restore the fragment's state here
            stepsArrayList = savedInstanceState.getParcelableArrayList(STEPS_LIST_INDEX);
        }

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
        mRecyclerView.setLayoutManager(mLayoutManager);
        Log.i("listSteps", stepsArrayList.size() + "");

        StepsAdapter stepsAdapter = new StepsAdapter(this, stepsArrayList);
        mRecyclerView.setAdapter(stepsAdapter);

        // Return the root view
        return rootView;
}

public void onClick(Steps stepClick){
        mCallback.onClick(stepClick);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveIn`enter code here`stanceState(outState);

        //Save the fragment's state here
        outState.putParcelableArrayList(STEPS_LIST_INDEX, stepsArrayList);
        super.onSaveInstanceState(outState);
    }  }

【问题讨论】:

    标签: android android-fragments android-recyclerview onitemclicklistener


    【解决方案1】:

    在recyclerview的每个item上实现点击功能的最好方法是在recyclerview viewholder中填充视图时初始化onClickListener。然后在 onClick 方法中,使用自定义接口/侦听器来捕获父片段/活动中的点击活动。

    例如:创建一个这样的自定义界面;

    public interface RecyclerviewOnClickListener{
    void recyclerviewClick(int position);
    }
    

    现在在您的包含回收站视图的父活动/片段中实现此接口。假设您的片段名称是 ChatFragment。那么,

    public class ChatFragment extends Fragment implements RecyclerviewOnClickListener{
    .
    .
    }
    

    这将在您的片段中实现 onClick(int position) 函数。在您的适配器构造函数中,您应该为 RecyclerviewOnClickListener 创建一个字段。假设你的适配器名称是 ChatAdapter,那么

    适配器构造函数。

    public ChatAdapter(RecyclerviewClickListener listener, .....<other params>){
    this.listener = listener;
    }
    

    在你的片段中,你可以像下面这样初始化你的适配器

    ChatAdapter adapter = new ChatAdapter(this, <any additional params>);
    

    您也应该将相同的“侦听器”实例传递给您的查看器,并在那里初始化侦听器

    现在在你的recyclerview ViewHolder中,你可以设置view.setOnClickListener(new OnClickListener{ this.listener.recyclerviewClick(getAdapterPosition()) });

    getAdapterPosition() 函数返回点击在recyclerview 中的位置,这将在你的fragment 中的recyclerviewClick() 函数中得到一个回调。

    关于你要传递的参数个数,你想用多少就用多少,但是对于recyclerview中的一个click函数,理想的方式是只用一个param,它的位置。现在您可以修改从片段传递到适配器的列表中的内容,并调用 notifyDataSetChanged() 来更新 recyclerview。希望清楚。

    【讨论】:

    • 嗯,这个答案确实很有帮助,但是即使没有接口也可以实现同样的效果,onClick也可以直接在Adapter的onBindViewHolder()中实现; :)
    • 是的,你说得对,onclick 功能也可以在适配器 onBindViewHolder 中实现。但我更喜欢在不涉及业务逻辑的视图中编写点击函数和初始化。这有助于查看器的可重用性
    • 这看起来也不错! :)
    • emilpmp,为什么要在Adapter中实现接口而不是Fragment?
    • @LeadBox4 '实现'片段中的接口。您需要通过构造函数将接口的实例传递给您的适配器。我已经编辑了答案
    【解决方案2】:

    在 OnBindviewHolder 中试试这个

     holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                  //code here
    
            }
    

    【讨论】:

      猜你喜欢
      • 2016-10-09
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多