简体   繁体   English

将 Button OnClick 与 Fragment 中 RecyclerView 内的 Row OnClick 分开

[英]Separate the Button OnClick from the Row OnClick inside RecyclerView in Fragment

I am trying to separate handle OnClick Button and OnClick Row inside Fragment with interface..我试图在带有界面的 Fragment 中分离处理 OnClick Button 和 OnClick Row ..

so far, this is what I have tried :到目前为止,这是我尝试过的:

Inside Fragment内部片段

if (recyclerView.getTag().toString().equals("Grid")) {
            adapter = new RVAdapter(ListOfdataAdapter, getContext(), 
                    RVAdapterChannel.ViewType.GRID_LIST_LAYOUT, new ClickListener() {
                @Override
                public void OnClick(int position, View view) {
                    //THIS ALWAYS RETURN ROW CLICKED
                    if (view.findViewById(R.id.imageLike).getId() == view.getId()){
                        Toast.makeText(getContext(), "IMAGE LIKE CLICKED",Toast.LENGTH_SHORT).show();
                        OpenDialog();
                    }
                    if (view.findViewById(R.id.layoutRelative).getId() == view.getId()){
                        Toast.makeText(getContext(), "ROW CLICKED", Toast.LENGTH_SHORT).show();
                        OpenDatabase();
                    }

                    //THIS MAKES APP CRASH
                    if (view.findViewById(R.id.imageLike).performClick){
                        Toast.makeText(getContext(), "IMAGE LIKE CLICKED",Toast.LENGTH_SHORT).show();
                        OpenDialog();
                    }
                    if (view.findViewById(R.id.layoutRelative).performClick){
                        Toast.makeText(getContext(), "ROW CLICKED", Toast.LENGTH_SHORT).show();
                        OpenDatabase();
                    }
                    // ANOTHER TRY
                }

                @Override
                public void onLongClicked(int position, View view) {
                }
            });

            recyclerView.setAdapter(adapter);
            if (getPreferenceValue().equals("on")) {
                AnimBottomToTop();
            }
        }

at the moment only one is in line with my expectation, that is, if I place If - Else inside the adapter.. but if I do, I cannot open OpenDialog (), OpenDatabase (), etc. If it can only be done through an adapter, how can I open OpenDialog();目前只有一个符合我的预期,就是如果我把If - Else放在adapter里面..但是如果我这样做了,我无法打开OpenDialog(),OpenDatabase()等,如果只能做到通过适配器,我怎样才能打开OpenDialog(); , OpenDatabase(); , OpenDatabase(); , etc? , 等等? and if possible I want to place it in fragments not in adapters.如果可能的话,我想将它放在片段中而不是在适配器中。

Inside Adapter内部适配器

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener{
        RelativeLayout Container;
        ImageView ImageLike;
        //...//
        private WeakReference<ClickListener> listenerRef;


        public ViewHolder(View itemView, ClickListener listener) {

            super(itemView);

            listenerRef = new WeakReference<>(listener);;
            ImageLike = (ImageView) itemView.findViewById(R.id.imageLike) ;
            //...//

            //itemView.setOnClickListener(this);
            itemView.setOnClickListener(this);
            Container.setOnClickListener(this);
            ImageLike.setOnClickListener(this);
            ImageLike.setOnLongClickListener(this);
        }

        // onClick Listener for view
        @Override
        public void onClick (View view) {
            //THIS WILL RETURN TOAST ON IMAGELIKE CLICK
            if (view.getId() == ImageLike.getId()) {
                Toast.makeText(view.getContext(), "IMAGE LIKE CLICKED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
            } //THIS WILL RETURN TOAST ON ROW CLICK
             else {
                Toast.makeText(view.getContext(), "ROW CLICKED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
            }
            listenerRef.get().OnClick(getAdapterPosition(), itemView);
        }

        //onLongClickListener for view
        @Override
        public boolean onLongClick(View view) {

            final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
            builder.setTitle("Hello Dialog")
                    .setMessage("LONG CLICK DIALOG WINDOW FOR ICON " + String.valueOf(getAdapterPosition()))
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });

            builder.create().show();
            listenerRef.get().onLongClicked(getAdapterPosition(), itemView);
            return true;
        }
    }

I use this method from here Onclick for each button inside RecyclerView items我从这里对 RecyclerView 项目中的每个按钮使用此方法Onclick

And from here RecyclerView onClick i think this not suit my needs to (not trying all answers)从这里RecyclerView onClick我认为这不适合我的需要(不尝试所有答案)

until now I have not found an answer according to my needs.直到现在我还没有根据我的需要找到答案。

forgive me if my question is difficult to understand.如果我的问题难以理解,请原谅我。 thanks for your response.感谢您的答复。

You can take OnClickListener s using the adapters constructor instead.您可以使用适配器构造函数来获取OnClickListener Therefore, you can set each click listener separately.因此,您可以单独设置每个点击侦听器。

class Adapter : RecyclerView.Adapter<ViewHolder> {

   OnClickListener buttonClick, rowClick;

   public Adapter(List<Data> data, OnClickListener buttonClick, OnClickListener rowClick) {
    this.buttonClick = buttonClick;
    this.rowClick = rowClick;
   }

   public void onBindViewHolder(ViewHolder v, int pos) {
      v.button.setOnClickListener(buttonClick);
      v.itemView.setOnClickListener(rowClick); // itemView is the whole view
      // other codes
   }
   // other parts of adapter
}

Then when you make the adapter, you can pass ClickListeners to it.然后当你制作适配器时,你可以将 ClickListeners 传递给它。

// when you make this list, like in the fragment

View.OnClickListener buttonListener = new View.OnClickListener {

   public void onClick(View v) {
       // button was clicked
   }
}

View.OnClickListener rowListener = new View.OnClickListener {

   public void onClick(View v) {
       // row was clicked
   }
}

Adapter adapter = new Adapter(listOfData, buttonListener, rowListener);
recyclerView.setAdapter(adapter);

TL; TL; DR DR

Pass two OnClickListener s as the adapter constructor param, and set the for views in onBindViewHolder .传递两个OnClickListener作为适配器构造函数参数,并在onBindViewHolder设置 for 视图。

Instead of itemView而不是itemView

listenerRef.get().OnClick(getAdapterPosition(), itemView);
listenerRef.get().onLongClicked(getAdapterPosition(), itemView);

return view from your onClick and onLongClick listener like below:从您的onClickonLongClick侦听器返回view ,如下所示:

listenerRef.get().OnClick(getAdapterPosition(), view);  
listenerRef.get().onLongClicked(getAdapterPosition(), view);

And then inside your fragment, do like this然后在你的片段中,这样做

@Override
public void OnClick(int position, View view) {

    if (R.id.imageLike == view.getId()){
        Toast.makeText(getContext(), "IMAGE LIKE CLICKED",Toast.LENGTH_SHORT).show();
        OpenDialog();
    }

    if (R.id.layoutRelative == view.getId()){
        Toast.makeText(getContext(), "ROW CLICKED", Toast.LENGTH_SHORT).show();
        OpenDatabase();
    }
}

On your adapter : Create interface for callback like bellow:在您的适配器上:为回调创建接口,如下所示:

public interface OnAdapterListener{
    void onImageLikeClicked();
    void onRowClicked();
    //Create more methods as per your need
}

Declare listener globally:全局声明监听器:

OnAdapterListener mListener;

Create method for initialize listener:初始化监听器的创建方法:

public void setOnClickListener(OnAdapterListener listener){
    mListener = listener;
}

OnClick method:点击方法:

// onClick Listener for view
@Override
public void onClick (View view) {
    //THIS WILL RETURN TOAST ON IMAGELIKE CLICK
    if (view.getId() == ImageLike.getId()) {
        Toast.makeText(view.getContext(), "IMAGE LIKE CLICKED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
        if(mListener != null){
            mListener.onImageLikeClicked();
        }
    } //THIS WILL RETURN TOAST ON ROW CLICK
    else {
        if(mListener != null){
            mListener.onRowClicked();
        }
        Toast.makeText(view.getContext(), "ROW CLICKED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
    }
}

From activity :从活动:

    adapter.setOnClickListener(new OnAdapterListener() {
        @Override
        public void onImageLikeClicked() {
            OpenDialog();
        }

        @Override
        public void onRowClicked() {
            OpenDatabase();
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM