【问题标题】:Interface Implementation for RecyclerView Android to Click ItemsRecyclerView Android点击Item的接口实现
【发布时间】:2020-03-10 02:20:37
【问题描述】:

我正在尝试在 Android 应用上制作可点击的 RecyclerView。代码没有错误,但是 RecyclerView 中的项目无法点击。对于 XML 代码中的“可点击”,这些项目设置为 true。我的猜测是问题出在界面的使用上,因为这对我来说相对较新。谢谢你的帮助。

package com.example.localmusic;

public interface OnBandVenueListener {
    void onBandVenueClick(int position);
}
----------------------------------------------------------------------------
package com.example.localmusic;

public class DisplayUserBandsVenues extends AppCompatActivity implements OnBandVenueListener {
private ActionBar actionBar;

private DatabaseReference mDatabase;
private FirebaseAuth mAuth;

private TextView bandOrVenue_textView;
private RecyclerView rvResults;

private Query band_query;
private Query venue_query;

private ArrayList<String> bands = new ArrayList<String>();
private ArrayList<String> venues = new ArrayList<String>();

private String update_band_or_venue;
private String userID;

private UserBandsVenuesAdapter mUserBandsVenuesAdapter;
private OnBandVenueListener mOnBandVenueListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_user_bands_venues);

    actionBar = getSupportActionBar();
    actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#FF0367BE")));

    mAuth = FirebaseAuth.getInstance();
    FirebaseUser fBUser = mAuth.getCurrentUser();
    userID = fBUser.getUid();

    mDatabase = FirebaseDatabase.getInstance().getReference();
    band_query = mDatabase.child("bands");
    venue_query = mDatabase.child("venues");

    update_band_or_venue = getIntent().getStringExtra("updateWhat");

    bandOrVenue_textView = findViewById(R.id.select_textView);
    rvResults = findViewById(R.id.bands_venues_recyclerView);

    bandOrVenue();
}

public void bandOrVenue() {
    if(update_band_or_venue.equals("band")) {
        bandOrVenue_textView.setText("Select Band to Update");

        band_query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    Band band = child.getValue(Band.class);

                    if(band.getBandAuth().equals(userID)) {
                        String band_name = band.getName();
                        bands.add(band_name);
                    }
                }

                mUserBandsVenuesAdapter = new UserBandsVenuesAdapter(bands, mOnBandVenueListener);
                rvResults.setAdapter(mUserBandsVenuesAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }
    else if(update_band_or_venue.equals("venue")) {
        bandOrVenue_textView.setText("Select Venue to Update");

        venue_query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    Venue venue = child.getValue(Venue.class);

                    if(venue.getVenueAuth().equals(userID)) {
                        String venue_name = venue.getName();
                        venues.add(venue_name);
                    }
                }

                mUserBandsVenuesAdapter = new UserBandsVenuesAdapter(venues,  mOnBandVenueListener);
                rvResults.setAdapter(mUserBandsVenuesAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }
    else {
        bandOrVenue_textView.setText("Error!");
    }

    rvResults.setLayoutManager(new LinearLayoutManager(this));
}

@Override
public void onBandVenueClick(int position) {
    Intent intent;

    if(update_band_or_venue.equals("band")) {
        intent = new Intent(this, UpdateBandInfo.class);
    }
    else if(update_band_or_venue.equals("venue")) {
        intent = new Intent(this, UpdateVenueInfo.class);
    }
    else {
        intent = new Intent(this, DisplayUserBandsVenues.class);
    }

    startActivity(intent);
}

---------------------------------------------------------------------------------
package com.example.localmusic;


public class UserBandsVenuesAdapter extends RecyclerView.Adapter<UserBandsVenuesAdapter.ViewHolder> {
private List<String> mResults;
private OnBandVenueListener mOnBandVenueListener;

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    public TextView bandVenue_name_textView;

    OnBandVenueListener onBandVenueListener;

    public ViewHolder(View itemView, OnBandVenueListener onBandVenueListener) {
        super(itemView);

        bandVenue_name_textView = itemView.findViewById(R.id.bandVenue_name_txtView);
        this.onBandVenueListener = onBandVenueListener;

        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        onBandVenueListener.onBandVenueClick(getAdapterPosition());
    }
}

public UserBandsVenuesAdapter(List<String> results, OnBandVenueListener onBandVenueListener) {
    mResults = results;
    mOnBandVenueListener = onBandVenueListener;
}

@NonNull
@Override
public UserBandsVenuesAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
                                                          int viewType) {
    Context context = parent.getContext();
    LayoutInflater inflater = LayoutInflater.from(context);

    View userBandsVenuesView = inflater.inflate(R.layout.band_venue_list_item, parent, false);

    UserBandsVenuesAdapter.ViewHolder viewHolder = new UserBandsVenuesAdapter.
            ViewHolder(userBandsVenuesView, mOnBandVenueListener);

    return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull UserBandsVenuesAdapter.ViewHolder viewHolder,
                             int position) {
    String result = mResults.get(position);

    TextView bandVenue_name_textView = viewHolder.bandVenue_name_textView;

    bandVenue_name_textView.setText(result);
}

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

使用 RecyclerView 显示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
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:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bluemusicoriginal"
tools:context=".DisplayUserBandsVenues">

<TextView
    android:id="@+id/select_textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:text="User Bands or Venues"
    android:textColor="#000000"
    android:textSize="30sp"
    android:textStyle="bold"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/bands_venues_recyclerView"
    android:layout_width="409dp"
    android:layout_height="680dp"
    android:layout_marginTop="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/select_textView" />
</androidx.constraintlayout.widget.ConstraintLayout>

列表项 XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
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/bandVenue_list_cl"
style="ListSeparator"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
    android:id="@+id/bandVenue_name_txtView"
    android:layout_width="307dp"
    android:layout_height="31dp"
    android:layout_marginStart="32dp"
    android:layout_marginTop="5dp"
    android:layout_marginEnd="32dp"
    android:layout_marginBottom="5dp"
    android:clickable="true"
    android:focusable="true"
    android:gravity="center"
    android:text="Band or Venue Name"
    android:textColor="#000000"
    android:textSize="30sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<View
    android:id="@+id/view"
    android:layout_width="match_parent"
    android:layout_height="2dp"
    android:background="#c0c0c0"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/bandVenue_list_cl" />
</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

  • 看起来好像没有调用 onClick 方法。
  • 这是有道理的,因为给定的代码会因为NullPointerException 而崩溃,如果它做到了那么远。当您单击某个项目时,您是否看到任何视觉反馈?请edit 向我们展示ActivityRecyclerView 项目布局。
  • Mike M:问题似乎是只要我不在包含乐队或场地名称的文本框中点击,我就可以点击该项目。
  • &lt;TextView&gt; 中删除android:clickable="true"android:focusable="true" 属性。那,以及下面萨达特的建议,应该这样做。
  • 是的!那成功了!非常感谢!

标签: android android-recyclerview interface onclick


【解决方案1】:

我想你只需要改变这一行

mUserBandsVenuesAdapter = new UserBandsVenuesAdapter(venues,  mOnBandVenueListener);

mUserBandsVenuesAdapter = new UserBandsVenuesAdapter(venues,  DisplayUserBandsVenues.this);

因为您将该接口实现到该 Activity 中。

【讨论】:

  • 显然没有调用接口的 onClick 方法。我在那里进行了调试测试,但失败了。
  • 您能再次更新您的代码吗?删除这一行 private OnBandVenueListener mOnBandVenueListener;,因为它总是 null
【解决方案2】:

试试这个

在你的适配器类中创建你的接口方法

    public interface ItemClickListener {
    void onItemClick(String text, int position);
}

然后在你的适配器类中创建一个 ItemClickListener 的变量

ItemClickListener mItemClickListener;

在你的适配器类中创建一个 onClickListener 方法

    public void onClickListener(YourAdapterName.ItemClickListener listener) {
    mItemClickListener = listener;
}

然后在adapter的onclicklistener项中添加这个

   if (mItemClickListener != null) {
            mItemClickListener.onItemClick(mData.get(position).getText(), position);
        }

然后让你的activity类实现YourAdapteName.ItemClickListener 并像这样在 OnclickListener 上设置您的适配器

yourAdapterName.onClickListener(this);

当你实现了 ItemClickListener 后,你将不得不覆盖 onItemClick 然后你在那里做任何你想做的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多