【问题标题】:Handle click event on CardView in a RecycleView在 RecycleView 中处理 CardView 上的单击事件
【发布时间】:2020-07-01 15:15:56
【问题描述】:

我正在尝试处理 RecycleView 中 CardView 的单击事件,但它不起作用。 这是样本:

在 RecyclerView 中显示数据的 Fragment:

public class SearchListFragment extends Fragment{

public static final String TAG = "SearchListFragment";
View rootView;
private RecyclerView recyclerView;
private ProListAdapter adapter;
ProgressDialog progressDialog;
String url;
String prof;
ArrayList<User> pros = new ArrayList<>();

public SearchListFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //Implementing View Pager
    rootView = inflater.inflate(R.layout.fragment_search_list, container, false);

    //RecyclerView
    recyclerView = rootView.findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new GridLayoutManager(rootView.getContext(), 3));

    return rootView;
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if (getArguments() != null) {
        url = getArguments().getString("url");
        prof = getArguments().getString("pro");
        sendRequest();
    }
}

private void sendRequest() {
    //Show ProgressDialog
    progressDialog = new ProgressDialog(getContext());
    progressDialog.setCancelable(false);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setTitle(getString(R.string.loading));
    progressDialog.setMessage(getString(R.string.dialog_wait));
    progressDialog.show();

    Map<String, String> params = new HashMap();

    params.put("prof", prof);



    StringRequest jsonObjReq = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            //Response OK
            ....
                    adapter = new ProListAdapter(pros, getContext());
                    recyclerView.setAdapter(adapter);
            ....
            progressDialog.dismiss();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            //error
            progressDialog.dismiss();
        }
    }){
        @Override
        protected Map<String, String> getParams()
        {
            return params;
        }
    };

    //Adding the request to the queue along with a unique string tag
    MySingleton.getInstance(getContext()).addToRequestQueue(jsonObjReq);
}

}

适配器:

public class ProListAdapter extends RecyclerView.Adapter<ProListAdapter.ViewHolder>{

private ArrayList<User> itemsData;
private Context context;

public ProListAdapter(ArrayList<User> itemsData, Context context) {
    this.itemsData = itemsData;
    this.context = context;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    // create a new view
    View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pro_card, null);

    // create ViewHolder
    ViewHolder viewHolder = new ViewHolder(itemLayoutView);

    return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    holder.nom.setText(itemsData.get(position).getName());
    holder.phone.setText(Long.toString(itemsData.get(position).getPhone()));
    holder.img.setImageResource(R.drawable.avatar);

    holder.card.setAnimation(AnimationUtils.loadAnimation(context, R.anim.zoom_in));
}

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

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView nom;
    public TextView phone;
    public ImageView img;
    public CardView card;
    public LinearLayout ly;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        ly = itemLayoutView.findViewById(R.id.ly);
        card = itemLayoutView.findViewById(R.id.card_pro);
        nom = itemLayoutView.findViewById(R.id.pro_nom);
        phone = itemLayoutView.findViewById(R.id.pro_phone);
        img = itemLayoutView.findViewById(R.id.pro_img);
        card.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(context, "info", Toast.LENGTH_LONG).show();
    }
}

}

单项布局 pro_card.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ly"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<androidx.cardview.widget.CardView
    android:id="@+id/card_pro"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginBottom="8dp"
    app:cardCornerRadius="3dp"
    app:cardElevation="3dp">
    <!-- Main Content View -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/cl"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content">
        <ImageView
            android:id="@+id/pro_img"
            android:layout_width="140dp"
            android:layout_height="130dp"
            android:src="@drawable/avatar"
            android:scaleType="centerInside"
            app:layout_constraintBottom_toTopOf="@id/pro_nom"
            app:layout_constraintStart_toStartOf="parent"/>

        <TextView
            android:id="@+id/pro_nom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:textSize="26sp"
            tools:text="@tools:sample/first_names"
            app:layout_constraintBottom_toTopOf="@id/pro_phone"
            app:layout_constraintStart_toStartOf="parent"/>

        <TextView
            android:id="@+id/pro_phone"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:textColor="#000000"
            android:textSize="20sp"
            tools:text="@tools:sample/us_phones"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

当我点击卡片时没有任何反应,有什么问题吗?我想知道在我的案例中是否有一种干净且正确的方法来实现 onClick。

【问题讨论】:

  • 尝试添加到 CardView 布局 android:clickable="true" 和父级 LinearLayout
  • 我试过但还是不行。
  • 尝试用LayoutInflater.from(parent.getContext()).inflate(R.layout.pro_card, parent,false);替换LayoutInflater.from(parent.getContext()).inflate(R.layout.pro_card, null);
  • 还是不行

标签: android android-recyclerview android-adapter android-cardview


【解决方案1】:

尝试在线性布局上添加点击监听 ly.setOnClickListener(this); 希望对你有帮助

【讨论】:

    【解决方案2】:

    在您的onBindViewHolder 中,您可以使用这样的 lambda: (我没有测试过)

    holder.itemLayoutView.setOnClickListener {(View v) -> {
       Toast.makeText(this, "info", Toast.LENGTH_LONG).show();
    });
    

    【讨论】:

      【解决方案3】:

      子视图正在使用触摸事件。要让CardView 获得控制权,您可以在自定义 CardView 中覆盖 onInterceptTouchEvent(MotionEvent ev),例如:

      public class ClickableCardView extends CardView {
      
          public ClickableCardView(Context context) {
              super(context);
          }
      
          public ClickableCardView(Context context, AttributeSet attrs) {
              super(context, attrs);
          }
      
          public ClickableCardView(Context context, AttributeSet attrs, int defStyleAttr) {
              super(context, attrs, defStyleAttr);
          }
      
          /**
           * Intercepts touch event from child views when true is returned.
           */
          @Override
          public boolean onInterceptTouchEvent(MotionEvent ev) {
              return true;
          }
      }
      

      并且在你的布局文件中使用你的 ClickableCardView,所以而不是:

      <androidx.cardview.widget.CardView>...</androidx.cardview.widget.CardView>
      

      您使用新的自定义视图(在您放置的任何包中):

      <com.company.app.ui.common.ClickableCardView>...</com.company.app.ui.common.ClickableCardView>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-22
        • 1970-01-01
        • 2021-03-13
        相关资源
        最近更新 更多