Android RecyclerView 没有显示任何内容
Android RecyclerView is showing nothing
我创建了一个应用程序,它在 Fragment 中有一个 RecyclerView 来显示数据库中的数据。
几周前,我创建了另一个带有 RecyclerView 和 android 支持包的应用程序,一切都很好。现在,使用 androidx,视图什么也不显示。
这是我的 RecyclerViewAdapter class:
public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecyclerViewAdapter.ViewHolder> {
private static final String TAG = "HistoryRecyclerView";
private List<HistoryType> mHistory;
HistoryRecyclerViewAdapter(List<HistoryType> history){
mHistory = history;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View historyView = inflater.inflate(R.layout.history_list_item,parent,false);
ViewHolder viewHolder = new ViewHolder(historyView);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
HistoryType history = mHistory.get(position);
SimpleDateFormat formatter;
Calendar calendar;
TextView nameText = holder.mNameText;
nameText.setText(history.getName());
TextView durationText = holder.mDurationText;
formatter = new SimpleDateFormat("HH:mm:ss");
calendar = Calendar.getInstance();
calendar.setTimeInMillis(history.getDuration());
String durationString = formatter.format(calendar.getTime());
durationText.setText(durationString);
TextView distanceText = holder.mDistanceText;
distanceText.setText(String.format("%.2f km",history.getDistance()));
TextView totalAirTimeText = holder.mTotalAirTimeText;
formatter = new SimpleDateFormat("mm:ss.SS");
calendar = Calendar.getInstance();
calendar.setTimeInMillis(history.getTotalAirTime());
String totalAirTimeString = formatter.format(calendar.getTime());
totalAirTimeText.setText(totalAirTimeString);
TextView dateText= holder.mDateText;
formatter = new SimpleDateFormat("dd MMMM yyyy");
String dateString = formatter.format(history.getDate());
dateText.setText(dateString);
}
@Override
public int getItemCount() {
return mHistory.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView mNameText;
public TextView mDurationText;
public TextView mDistanceText;
public TextView mTotalAirTimeText;
public TextView mDateText;
public ViewHolder(View itemView) {
super(itemView);
mNameText = (TextView) itemView.findViewById(R.id.history_name);
mDurationText = (TextView) itemView.findViewById(R.id.history_duration);
mDistanceText = (TextView) itemView.findViewById(R.id.history_distance);
mTotalAirTimeText = (TextView) itemView.findViewById(R.id.history_airtime);
mDateText = (TextView) itemView.findViewById(R.id.history_date);
}
}
这里是调用适配器的片段(ArrayList 有一项):
public class HistoryFragment extends Fragment {
private ArrayList<HistoryType> mHistoryList = new ArrayList<>();
private RecyclerView mRecyclerView;
private HistoryRecyclerViewAdapter mHistoryAdapter;
private SQLiteOpenHelper mSqliteOpenHelper;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_history, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.history_recycler);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHistoryAdapter = new HistoryRecyclerViewAdapter(mHistoryList);
mRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
mRecyclerView.setAdapter(mHistoryAdapter);
mSqliteOpenHelper = new SQLiteOpenHelper(getActivity());
mHistoryList = mSqliteOpenHelper.getHistory();
for (HistoryType dataSet: mHistoryList) {
mHistoryAdapter.notifyItemInserted(mHistoryList.indexOf(dataSet));
}
}
fragment_history.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
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="match_parent"
android:id="@+id/history_recycler"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/text_margin"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
history_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
//Name
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_name"
android:layout_margin="@dimen/text_margin"
android:text="activity name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="@dimen/big_text_size"
android:textStyle="bold"
/>
//Duration
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_duration_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
android:layout_marginLeft="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toLeftOf="parent"
android:background="@drawable/timer_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_duration"
android:text="01.01.2021"
android:layout_margin="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_duration_icon"
android:textSize="@dimen/medium_text_size"/>
//Distance
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_distance_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_duration"
android:background="@drawable/arrow_right_alt_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_distance"
android:text="1h 35min"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_distance_icon"
android:textSize="@dimen/medium_text_size"/>
//Total Airtime
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_airtime_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_distance"
android:background="@drawable/keyboard_arrow_up_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_airtime"
android:text="1h 35min"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_airtime_icon"
android:textSize="@dimen/medium_text_size"/>
//Date
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_date"
android:text="01.01.2021"
android:layout_margin="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_duration_icon"
app:layout_constraintLeft_toLeftOf="parent"
android:textSize="@dimen/small_text_size" />
</androidx.constraintlayout.widget.ConstraintLayout>
有人帮我吗?
非常感谢
据我所知,您的参考资料有问题。首先,您使用 ArrayList 的一个空实例声明您的适配器,这是可以的。适配器现在与此 ArrayList 连接。但是随后您将列表重新分配给另一个实例,即从
返回的实例
mSqliteOpenHelper.getHistory()
如果比较这两个实例,您会发现它们并不相同。您应该做的是使用 'addAll()'.
将 'mSqliteOpenHelper.getHistory()' 的结果添加到已经与适配器连接的列表(您已经定义的空 ArrayList)
编辑:
只是为了让自己更清楚:
一开始你声明并初始化你的列表
private ArrayList<HistoryType> mHistoryList = new ArrayList<>();
我们称此实例为 Instance#1。您将 Instance#1 设置为适配器的数据源。适配器现在有一个空数据源。
之后,您重新分配此列表
mHistoryList = mSqliteOpenHelper.getHistory();
这是一个不同的 ArrayList 实例,我们称它为 Instance#2。尽管 mHistoryList 变量保存了这个实例,适配器仍然与 Instance#1 链接,只是你不再有对它的引用。因此适配器与空的 ArrayList (Instance#1) 链接,而不是与具有数据的 ArrayList (Instance#2) 链接。
不要重新分配变量,使其成为最终变量。 ArrayList 是可变的,因此您可以向其中添加数据。因此,将数据添加到其中并通知适配器它已被更改。
如果您有任何问题,请告诉我
我创建了一个应用程序,它在 Fragment 中有一个 RecyclerView 来显示数据库中的数据。 几周前,我创建了另一个带有 RecyclerView 和 android 支持包的应用程序,一切都很好。现在,使用 androidx,视图什么也不显示。 这是我的 RecyclerViewAdapter class:
public class HistoryRecyclerViewAdapter extends RecyclerView.Adapter<HistoryRecyclerViewAdapter.ViewHolder> {
private static final String TAG = "HistoryRecyclerView";
private List<HistoryType> mHistory;
HistoryRecyclerViewAdapter(List<HistoryType> history){
mHistory = history;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View historyView = inflater.inflate(R.layout.history_list_item,parent,false);
ViewHolder viewHolder = new ViewHolder(historyView);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
HistoryType history = mHistory.get(position);
SimpleDateFormat formatter;
Calendar calendar;
TextView nameText = holder.mNameText;
nameText.setText(history.getName());
TextView durationText = holder.mDurationText;
formatter = new SimpleDateFormat("HH:mm:ss");
calendar = Calendar.getInstance();
calendar.setTimeInMillis(history.getDuration());
String durationString = formatter.format(calendar.getTime());
durationText.setText(durationString);
TextView distanceText = holder.mDistanceText;
distanceText.setText(String.format("%.2f km",history.getDistance()));
TextView totalAirTimeText = holder.mTotalAirTimeText;
formatter = new SimpleDateFormat("mm:ss.SS");
calendar = Calendar.getInstance();
calendar.setTimeInMillis(history.getTotalAirTime());
String totalAirTimeString = formatter.format(calendar.getTime());
totalAirTimeText.setText(totalAirTimeString);
TextView dateText= holder.mDateText;
formatter = new SimpleDateFormat("dd MMMM yyyy");
String dateString = formatter.format(history.getDate());
dateText.setText(dateString);
}
@Override
public int getItemCount() {
return mHistory.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView mNameText;
public TextView mDurationText;
public TextView mDistanceText;
public TextView mTotalAirTimeText;
public TextView mDateText;
public ViewHolder(View itemView) {
super(itemView);
mNameText = (TextView) itemView.findViewById(R.id.history_name);
mDurationText = (TextView) itemView.findViewById(R.id.history_duration);
mDistanceText = (TextView) itemView.findViewById(R.id.history_distance);
mTotalAirTimeText = (TextView) itemView.findViewById(R.id.history_airtime);
mDateText = (TextView) itemView.findViewById(R.id.history_date);
}
}
这里是调用适配器的片段(ArrayList 有一项):
public class HistoryFragment extends Fragment {
private ArrayList<HistoryType> mHistoryList = new ArrayList<>();
private RecyclerView mRecyclerView;
private HistoryRecyclerViewAdapter mHistoryAdapter;
private SQLiteOpenHelper mSqliteOpenHelper;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_history, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.history_recycler);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mHistoryAdapter = new HistoryRecyclerViewAdapter(mHistoryList);
mRecyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
mRecyclerView.setAdapter(mHistoryAdapter);
mSqliteOpenHelper = new SQLiteOpenHelper(getActivity());
mHistoryList = mSqliteOpenHelper.getHistory();
for (HistoryType dataSet: mHistoryList) {
mHistoryAdapter.notifyItemInserted(mHistoryList.indexOf(dataSet));
}
}
fragment_history.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
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="match_parent"
android:id="@+id/history_recycler"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/text_margin"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
history_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
//Name
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_name"
android:layout_margin="@dimen/text_margin"
android:text="activity name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="@dimen/big_text_size"
android:textStyle="bold"
/>
//Duration
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_duration_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
android:layout_marginLeft="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toLeftOf="parent"
android:background="@drawable/timer_24" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_duration"
android:text="01.01.2021"
android:layout_margin="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_duration_icon"
android:textSize="@dimen/medium_text_size"/>
//Distance
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_distance_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_duration"
android:background="@drawable/arrow_right_alt_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_distance"
android:text="1h 35min"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_distance_icon"
android:textSize="@dimen/medium_text_size"/>
//Total Airtime
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_airtime_icon"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/text_margin"
android:layout_marginRight="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_distance"
android:background="@drawable/keyboard_arrow_up_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_airtime"
android:text="1h 35min"
android:layout_marginTop="@dimen/text_margin"
android:layout_marginLeft="@dimen/icon_margin"
app:layout_constraintTop_toBottomOf="@id/history_name"
app:layout_constraintLeft_toRightOf="@id/history_airtime_icon"
android:textSize="@dimen/medium_text_size"/>
//Date
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/history_date"
android:text="01.01.2021"
android:layout_margin="@dimen/text_margin"
app:layout_constraintTop_toBottomOf="@id/history_duration_icon"
app:layout_constraintLeft_toLeftOf="parent"
android:textSize="@dimen/small_text_size" />
</androidx.constraintlayout.widget.ConstraintLayout>
有人帮我吗? 非常感谢
据我所知,您的参考资料有问题。首先,您使用 ArrayList 的一个空实例声明您的适配器,这是可以的。适配器现在与此 ArrayList 连接。但是随后您将列表重新分配给另一个实例,即从
返回的实例mSqliteOpenHelper.getHistory()
如果比较这两个实例,您会发现它们并不相同。您应该做的是使用 'addAll()'.
将 'mSqliteOpenHelper.getHistory()' 的结果添加到已经与适配器连接的列表(您已经定义的空 ArrayList)编辑: 只是为了让自己更清楚: 一开始你声明并初始化你的列表
private ArrayList<HistoryType> mHistoryList = new ArrayList<>();
我们称此实例为 Instance#1。您将 Instance#1 设置为适配器的数据源。适配器现在有一个空数据源。
之后,您重新分配此列表
mHistoryList = mSqliteOpenHelper.getHistory();
这是一个不同的 ArrayList 实例,我们称它为 Instance#2。尽管 mHistoryList 变量保存了这个实例,适配器仍然与 Instance#1 链接,只是你不再有对它的引用。因此适配器与空的 ArrayList (Instance#1) 链接,而不是与具有数据的 ArrayList (Instance#2) 链接。 不要重新分配变量,使其成为最终变量。 ArrayList 是可变的,因此您可以向其中添加数据。因此,将数据添加到其中并通知适配器它已被更改。
如果您有任何问题,请告诉我