本文介绍了Android:并非每次都显示RecyclerView的CardView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MainActivity中有一个RecyclerView,它显示CardViews列表,并且工作正常.单击CardView即可完成RecyclerView活动,并启动一个Detail Activity,该活动在新的RecyclerView列表中显示已单击的CardView. Detail Activity仅用于在RecyclerView中显示单个CardView(这样做是为了让用户可以在CardView上使用RecyclerView的ItemTouchHelper.SimpleCallback代码,以便向用户轻松滑动).

I have a RecyclerView in MainActivity that shows a list of CardViews and that is working properly. A click on the CardView finishes the RecyclerView Activity and launches a Detail Activity that shows the clicked on CardView in a new RecyclerView list. The Detail Activity is used only to show that single CardView in a RecyclerView (I do this so I can use RecyclerView's ItemTouchHelper.SimpleCallback code on the CardView for easy left swipe for the user).

这是问题所在:我点击了明细活动的工具栏上的左尖号以返回到MainActivity.然后,单击完全相同的CardView即可使用户返回到明细活动.但是这一次仅显示背景视图(边框). CardView及其数据库数据的视图完全丢失.

Here is the problem: I hit the left caret on the Detail Activity's Toolbar to return to the MainActivity. Then a click on the exact same CardView brings the user back to the Detail Activity. But this time only the background View (a border) is showing. The view of the CardView and its database data is completely missing.

该错误似乎是随机发生的.我可以单击从MainActivity到来回详细活动5次成功,然后在第六次尝试,没有CardView将显示在详细活动中.否则,我将成功单击两次,然后单击第三次,详细信息活动"中的CardView将不会显示.请注意,Detail Activity中的左尖号单击使用onBackPressed(),因此Detail Activity完成.因此,我认为不应有任何堆栈问题.我还尝试将CardView的xml高度调整为match_parent而不是wrap_content,但是没有运气.到存储库到Dao的Detail Activity的ViewModel返回包装在LiveData中的列表.也许ViewModel存在观察者问题,但是我认为当Detail Activity被销毁时观察者会被移除/破坏?我在这里想念什么?

The error appears to happen randomly. I can click to go from the MainActivity to the Detail Activity back and forth 5 times successfully and then on the sixth try, no CardView will show in the Detail Activity. Or I'll click two times successfully and then the third time, the CardView in the Detail Activity will not show. Note the left caret click in Detail Activity uses onBackPressed() so the Detail Activity finishes. So I don't think there should be any backstack issues. I also tried to adjust the xml height for the CardView to match_parent rather than wrap_content but no luck. The Detail Activity's ViewModel to Repository to Dao returns a List wrapped in LiveData. Perhaps there is an observer problem with the ViewModel, but I thought the observer gets removed/destroyed when the Detail Activity is destroyed? What am I missing here?

适配器

...
itemHolder.cardView.setOnClickListener(view -> {

Card adapterItem= TodosAdapter.this.getItem(itemHolder.getAdapterPosition());
            int adapPos = itemHolder.getAdapterPosition();
            if (adapPos !=RecyclerView.NO_POSITION) {
                onItemClick(adapPos, adapterItem);
            }
        });

MainActivity

MainActivity

...
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();

DetailActivity

DetailActivity

...
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

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

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

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"
            ...
}

ViewModel

ViewModel

...
LiveData<List<Card>> getSingleCard(int cardId) {
    return repository.getSingleCard(cardId);
}

存储库

...
 public LiveData<List<Card>> getSingleCard(int cardId) {
    return quickcardDao.getSingleCard(cardId);
}

Dao

...
@Query("SELECT * FROM cards WHERE cardId = :cardId LIMIT 1")
LiveData<List<Card>> getSingleCard(int cardId);

推荐答案

因此,如果数据不变,则返回相同的DetailActivity将不会刷新视图.答案是如果数据未更改,则重新使用LiveData(而不是从数据库重新加载LiveData).请参阅ViewModel的Android开发者体系结构组件指南,有关解决我的问题的"loadUsers()"示例的实现ViewModel"部分: https://developer.android.com/topic/libraries/architecture/viewmodel .

So if the data does not change then going back to the same DetailActivity will not refresh the View. The answer was to re-use the LiveData (rather than re-loading the LiveData again from the database) if the data has not changed. See the Android Developers Architecture Components guide for ViewModel, "Implement a ViewModel" section for the "loadUsers()" example that solved my problem: https://developer.android.com/topic/libraries/architecture/viewmodel.

这篇关于Android:并非每次都显示RecyclerView的CardView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-02 02:12