我有一个视图,我希望将其设置为可单击以打开新活动。该代码运行没有任何错误,但是当我单击主要活动中的列表时,什么也没有发生。列表显示正常,但是当单击特定数据时,什么也没有发生。这是适配器的代码
package com.example.helpresponse;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Locale;
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
@NonNull
@Override
public TargetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
/*
viewHolder.myClickableView.setOnClickListener((v) -> {
Intent intent = new Intent(context, MapsActivity.class);
//int myData = 1;
//intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
});
*/
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Do your stuff
Intent intent = new Intent(context, MapsActivity.class);
int myData = 1;
intent.putExtra("myDataKey", myData);
//more intent.putExtra(s) as needed
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
if(targetsArrayList == null)
return 0;
return targetsArrayList.size();
}
public class TargetViewHolder extends RecyclerView.ViewHolder {
protected TextView androidTargetName;
protected TextView androidTargetNumber;
protected TextView androidTargetShortName;
protected LinearLayout myClickableView;
public TargetViewHolder(@NonNull View itemView) {
super(itemView);
myClickableView = itemView.findViewById(R.id.linearLayout);
androidTargetShortName = itemView.findViewById(R.id.textView2);
androidTargetName = itemView.findViewById(R.id.textView3);
androidTargetNumber = itemView.findViewById(R.id.textView4);
}
}
public interface HandleClick {
void onItemClick(int index);
}
}
此代码是主要活动
package com.example.helpresponse;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
RecyclerView.Adapter adapter ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new RecyclerViewAdapter(ShowStudentDetailsActivity.this, list);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
此代码是layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
>
<TextView
android:id="@+id/textView2"
android:textColor="@color/colorPrimary"
style="@style/Base.TextAppearance.AppCompat.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text="textview"
android:minWidth="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"/>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView2"
app:layout_constraintTop_toTopOf="parent"
android:clickable="true"
>
<TextView
android:id="@+id/textView3"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginBottom="8dp"
android:text="textview"
android:clickable="true"/>
<TextView
android:layout_marginTop="8dp"
android:id="@+id/textView4"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="textview"
android:clickable="true"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
请帮助,谢谢
答案 0 :(得分:0)
您没有使用实现,这应该可以解决您的问题。
public class ShowStudentDetailsActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
List<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
...
adapter = new TargetDataAdapter(list);
答案 1 :(得分:0)
首先,您创建了一个自定义适配器,并且没有使用它。 其次,您正在尝试通过抽象适配器的某些功能(例如onClickListeners)来减轻适配器的工作量,但是您仍然在适配器内部执行onClick,这几乎破坏了抽象的目的。 最后,接口基本上是要实现的,我很好奇您是如何错过的。
下面是代码的注释正确片段,只有当您阅读注释时,您才能更好地理解它。
第一个适配器:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
ArrayList<AndroidTargets> targetsArrayList;
private Context context;
private HandleClick mHandleClick;
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData) {
targetsArrayList = mTargetData;
}
public void setmHandleClick(HandleClick handleClick) {
this.mHandleClick = handleClick;
}
@NonNull
@Override
public TargetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
context = viewGroup.getContext();
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Do your stuff
mHandleClick.onItemClick(i);//here is where you call the onItemClick method in the interface
}
});
}
public interface HandleClick {
void onItemClick(int index);
}
}
您的ShowStudentDetails活动:
//Take note of the implements keyword
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
DatabaseReference databaseReference;
ProgressDialog progressDialog;
ArrayList<StudentDetails> list = new ArrayList<>();
RecyclerView recyclerView;
TargetDataAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ShowStudentDetailsActivity.this));
progressDialog = new ProgressDialog(ShowStudentDetailsActivity.this);
progressDialog.setMessage("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list);
/*The this keyword below parses whatever setmHandleClick() method needs that's present in that same class, which is the onItemClick() method in the interface that we implemented. So, the this keyword simply is a reference to ShowStudentDetailsActivity as an object, including all it resources like context */
adapter.setmHandleClick(this)
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
/* This is the result of the implemented interface above using implements keyword
you will note that without the below method, our class will show error and it's
basically telling us to do like below. So, when you implement an interface, you will be forced to have all its method implemented like below also.
I will suggest you read more on interface in java.*/
@Override
void onItemClick(int index){
//note that we have moved the code that was in the adapter back to the activity it self.
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}
就是这样。
奖金,下面是更好的方法和可读性更高的版本。
首先,我将界面放在单独的文件中。
public interface HandleClick {
void onItemClick(int index);
}
第二个我的适配器:
public class TargetDataAdapter extends RecyclerView.Adapter<TargetDataAdapter.TargetViewHolder>{
private ArrayList<AndroidTargets> targetsArrayList;
private HandleClick mHandleClick;
/*Note that the constructor now take two params which helps us get ride of setmHandleClick() method.*/
public TargetDataAdapter(ArrayList<AndroidTargets> mTargetData, HandleClick handleClick) {
targetsArrayList = mTargetData;
mHandleClick = handleClick;
}
@NonNull
@Override
public TargetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.target_row,viewGroup,false);
return new TargetViewHolder(v);
}
/* There is an interesting way to make below code neater by abstracting it back to the Activity incharge, let me know if you want that...priority now is to focus on fixing your issue. */
@Override
public void onBindViewHolder(@NonNull TargetViewHolder viewHolder, int i) {
viewHolder.androidTargetName.setText(targetsArrayList.get(i).FIELD1 );
viewHolder.androidTargetNumber.setText(String.format(Locale.getDefault(), "API Level: %d", targetsArrayList.get(i).FIELD2));
viewHolder.androidTargetShortName.setText(targetsArrayList.get(i).FIELD3);
viewHolder.myClickableView.setClickable(true);
viewHolder.myClickableView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mHandleClick.onItemClick(i);
}
});
}
}
我的ShowStudentDetails活动:
//Note that you can implement more than one interfaces, that's one of it's beauty.
public class ShowStudentDetailsActivity extends AppCompatActivity, implements HandleClick {
private DatabaseReference databaseReference;
ProgressDialog progressDialog;
private ArrayList<StudentDetails> list = new ArrayList<>();
private RecyclerView recyclerView;
private TargetDataAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_student_details);
initRecyclerView();
initProgressDialog("Loading Data from Firebase Database");
progressDialog.show();
databaseReference = FirebaseDatabase.getInstance().getReference("Police").child("Chats");
databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
StudentDetails studentDetails = dataSnapshot.getValue(StudentDetails.class);
list.add(studentDetails);
}
adapter = new TargetDataAdapter(list, this);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
@Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
private void initProgressDialog(String msg){
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(msg);
}
private void initRecyclerView(){
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
/*LinearLayoutManager.VERTICAL is to set the orientation of my list items in the recyclerView, and the boolean value When set to true, layouts from end to start, otherwise start to end.*/
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
}
@Override
void onItemClick(int index){
Intent intent = new Intent(this, MapsActivity.class);
int myData = index;
intent.putExtra("myDataKey", myData);
startActivity(intent);
}
}
答案 2 :(得分:0)
即使您未在MainActivity中使用,问题也出在与您的接口上。 例如如何实现界面。
步骤:1在适配器中创建接口:
public interface IHomeSelector{
void onCategorySelected(int postion);
}
步骤:2在ViewHolder使用界面
公共类ViewHolder扩展了RecyclerView。ViewHolder实现了View.OnClickListener {
private TextView category;
private ImageView category_icon;
private IHomeSelector iHomeSelector;
public ViewHolder(@NonNull View itemView, IHomeSelector iHomeSelector) {
super(itemView);
category = itemView.findViewById(R.id.category_title);
category_icon = itemView.findViewById(R.id.category_icon);
this.iHomeSelector = iHomeSelector;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
iHomeSelector.onCategorySelected(getAdapterPosition());
}
}
步骤:3通过适配器构造函数中的接口
public class HomeRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<String> mCategories = new ArrayList<>();
private Context mContext;
private IHomeSelector mIHomeSelector;
public HomeRecyclerAdapter(ArrayList<String> mCategories, Context mContext, IHomeSelector mIHomeSelector) {
this.mCategories = mCategories;
this.mContext = mContext;
this.mIHomeSelector = mIHomeSelector;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_category_list_item, null);
return new ViewHolder(view, mIHomeSelector);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
((ViewHolder)viewHolder).category.setText(mCategories.get(i));
RequestOptions requestOptions = new RequestOptions()
.error(R.drawable.ic_launcher_background);
Drawable iconResource = null;
switch(mCategories.get(i)){
case "Music":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_audiotrack_white_24dp);
break;
}
case "Podcasts":{
iconResource = ContextCompat.getDrawable(mContext, R.drawable.ic_mic_white_24dp);
break;
}
}
Glide.with(mContext)
.setDefaultRequestOptions(requestOptions)
.load(iconResource)
.into(((ViewHolder)viewHolder).category_icon);
}
@Override
public int getItemCount() {
return mCategories.size();
}
活动中的上一步工具界面:
public class HomeFragment extends Fragment implements HomeRecyclerAdapter.IHomeSelector
{
private static final String TAG = "HomeFragment";
// UI Components
private RecyclerView mRecyclerView;
// Vars
private HomeRecyclerAdapter mAdapter;
private ArrayList<String> mCategories = new ArrayList<>();
private IMainActivity mIMainActivity;
public static HomeFragment newInstance(){
return new HomeFragment();
}
@Override
public void onHiddenChanged(boolean hidden) {
if(!hidden){
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
initRecyclerView(view);
mIMainActivity.setActionBarTitle(getString(R.string.categories));
}
private void initRecyclerView(View view){
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAdapter = new HomeRecyclerAdapter(mCategories, getActivity(), this); // passing 3 rd parameter this for interface
mRecyclerView.setAdapter(mAdapter);
}
@Override
public void onCategorySelected(int postion) {
Log.d(TAG, "onCategorySelected: list item is clicked!");
//Here implement you code not in adapter
}
}
如果仍然遇到问题,请按照此步骤操作。祝您编码愉快!