Android:并非每次都显示RecyclerView的CardView

时间:2019-08-25 23:49:48

标签: android-layout android-recyclerview android-cardview

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

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

该错误似乎是随机发生的。我可以单击从MainActivity到来回详细活动5次,然后第六次尝试,没有CardView将显示在详细活动中。否则,我将成功单击两次,然后单击第三次,Detail Activity中的CardView将不会显示。请注意,“详细信息活动”中的左尖号单击使用onBackPressed(),以便“详细活动”完成。因此,我认为不应有任何堆栈问题。我还尝试将CardView的xml高度调整为match_parent而不是wrap_content,但是没有运气。到存储库到Dao的Detail Activity的ViewModel返回包装在LiveData中的列表。也许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);
            }
        });

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

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

ViewModel

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

1 个答案:

答案 0 :(得分:0)

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