【发布时间】:2019-08-25 23:49:48
【问题描述】:
我在 MainActivity 中有一个 RecyclerView,它显示了 CardViews 列表并且工作正常。点击 CardView 完成 RecyclerView Activity 并启动一个 Detail Activity,在新的 RecyclerView 列表中显示点击的 CardView。 Detail Activity 仅用于在 RecyclerView 中显示单个 CardView(我这样做是为了在 CardView 上使用 RecyclerView 的 ItemTouchHelper.SimpleCallback 代码,以便用户向左滑动)。
这是问题所在:我点击了 Detail Activity 工具栏上的左插入符以返回 MainActivity。然后单击完全相同的 CardView 将用户带回 Detail Activity。但这次只显示背景视图(边框)。 CardView 及其数据库数据的视图完全丢失。
错误似乎是随机发生的。我可以点击从MainActivity到Detail Activity来回成功5次,然后在第六次尝试时,Detail Activity中不会显示CardView。或者我点击两次成功,然后第三次,DetailActivity中的CardView就不显示了。请注意 Detail Activity 中的左插入符号单击使用 onBackPressed() ,因此 Detail Activity 完成。所以我认为不应该有任何后堆栈问题。我还尝试将 CardView 的 xml 高度调整为 match_parent 而不是 wrap_content 但没有运气。 Detail Activity 的 ViewModel 到 Repository 到 Dao 返回一个包裹在 LiveData 中的 List。也许 ViewModel 存在观察者问题,但我认为当 Detail Activity 被销毁时,观察者会被移除/销毁?我在这里错过了什么?
适配器
...
itemHolder.cardView.setOnClickListener(view -> {
Card adapterItem= TodosAdapter.this.getItem(itemHolder.getAdapterPosition());
int adapPos = itemHolder.getAdapterPosition();
if (adapPos !=RecyclerView.NO_POSITION) {
onItemClick(adapPos, adapterItem);
}
});
主活动
...
public void onItemClick(int clickPos, Card cardFromClick) {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("TAG","fromMain");
intent.putExtra("itemFromMain", cardFromClick);
startActivity(intent);
finish();
详细活动
...
public class DetailActivity extends AppCompatActivity {
private int cardId = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
// Get a new or existing ViewModel from the ViewModelProvider.
detsViewModel = new ViewModelProvider(this).get(CardViewModel.class);
Toolbar toolbar = findViewById(R.id.toolbar);
// The left caret is for Up navigation to the previous activity
// for OS versions 4.0 and earlier.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationIcon(R.drawable.ic_action_previous_item);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
}
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
String classname = extras.getString("TAG");
// The user clicked on a Card in the MainActivity
if (classname != null && classname.equals("fromMain")) {
card = extras.getParcelable("itemFromMain");
if (card != null) {
cardId = card.getId(); // card data is stored in Room database.
}
}
}
detsViewModel.getSingleCard(cardId).observe(this, singleAdapterList -> {
adapter2.setCardList(singleAdapterList);
});
}
activity_details.xml
...
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
tools:context=".DetailsActivity" >
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" >
</include>
<RelativeLayout
android:id="@+id/todoListLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar" >
<TextView
android:id="@+id/Card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="Card"
android:textStyle="bold"
android:textColor="@color/text_primary"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerHorizontal="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/details_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/Card"
android:scrollbars="vertical" />
<TextView
android:id="@+id/skytext5"
android:text="Cards"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/details_recyclerview"
android:background="@color/colorPrimary"
android:textAppearance="?android:attr/textAppearanceMedium"
android:clickable="true"
android:focusable="true" />
</RelativeLayout>
DetailsAdapter
...
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.details_list_item, parent, false);
}
private List<Card> oneCardList
public void setCardList(List<Card> singleCardList) {
if (oneCardList != null) {
oneCardList.clear();
this.oneCardList = singleCardList;
} else {
// First initialization
this.oneCardList = singleCardList;
}
}
details_list_item.xml
...
<FrameLayout
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/detsinglecard_view"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"
android:foreground="?android:attr/selectableItemBackground"
android:background="#FFFFFF"
tools:context=".DetailActivity">
<RelativeLayout
android:id="@+id/view_background2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
...
</RelativeLayout>
<RelativeLayout
android:id="@+id/view_foreground2"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/colorFlLabelFinal" >
<androidx.cardview.widget.CardView
android:id="@+id/cardview_dets"
android:layout_height="match_parent"
android:layout_width="match_parent"
...
}
视图模型
...
LiveData<List<Card>> getSingleCard(int cardId) {
return repository.getSingleCard(cardId);
}
存储库
...
public LiveData<List<Card>> getSingleCard(int cardId) {
return quickcardDao.getSingleCard(cardId);
}
道
...
@Query("SELECT * FROM cards WHERE cardId = :cardId LIMIT 1")
LiveData<List<Card>> getSingleCard(int cardId);
【问题讨论】:
-
在此处添加断点 if (extras != null) here if (classname != null && classname.equals("fromMain")) and here if (card != null)该卡为空。好像卡号的值没有被正确传递。
-
@hfarhanahmed DetailActivity 中的卡片永远不应为空,因为用户总是单击 MainActivity 中的卡片。我在 "card = card.getId()": "Toast.makeText(DetailActivity.this, "" + cardId, Toast.LENGTH_SHORT).show();" 之后使用此 Toast 确认 Room 数据库中的 cardId 值是正确的
-
ID 是正确的,仍然没有显示数据?
-
是的。因此,我认为这一定是 ViewModel 及其观察者的问题。
-
adapter2.setCardList(singleAdapterList);分享一下这个功能的实现
标签: android-layout android-recyclerview android-cardview