![](/img/trans.png)
[英]How to save and restore RecyclerView Items's positions using Json
[英]How to save items added in RecyclerView?
我有一個 RecyclerView 但我面臨一些問題。 每當我向回收站視圖添加一些東西時,例如切換片段或關閉應用程序,RecyclerView 中的所有項目都會消失。 有辦法拯救他們嗎? 你能幫忙的話,我會很高興!
這是一些代碼,看看是否有人需要它:
適配器
package com.example.freetrialtracker;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class SubTrialAdapter extends RecyclerView.Adapter<SubTrialAdapter.MyViewHolder>{
private ArrayList<SubTrial> listData;
private Context context;
private OnEditListener onEditListener;
public SubTrialAdapter(Context context, ArrayList<SubTrial> list,OnEditListener onEditListener){
this.listData=list;
this.context=context;
this.onEditListener=onEditListener;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View viewItem= LayoutInflater.from(parent.getContext()).inflate(R.layout.subscription_card_view,parent,false);
return new MyViewHolder(viewItem);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
SubTrial dataObj=listData.get(position);
holder.nameTxt.setText(dataObj.getNamee());
holder.startDate.setText(dataObj.getStartDate());
holder.endDate.setText(dataObj.getEndDate());
holder.description.setText(dataObj.getDescription());
holder.link.setText(dataObj.getLink());
holder.imgDelete.setOnClickListener(v->{
listData.remove(position);
notifyDataSetChanged();
});
holder.imgEdit.setOnClickListener(v->{
onEditListener.onEditClick(listData.get(position),position);
});
}
@Override
public int getItemCount() {
return listData.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameTxt,startDate,endDate,description,link;
ImageView imgEdit,imgDelete;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
nameTxt=itemView.findViewById(R.id.nameTxtId);
startDate=itemView.findViewById(R.id.startDateTxtId);
endDate = itemView.findViewById(R.id.endDateTxtId);
description = itemView.findViewById(R.id.descriptionId);
link = itemView.findViewById(R.id.linkId);
imgEdit=itemView.findViewById(R.id.imgEdit);
imgDelete=itemView.findViewById(R.id.imgDelete);
}
}
public void editData(SubTrial listDataObj,int currentPosition){
listData.get(currentPosition).setLink(listDataObj.getLink());
listData.get(currentPosition).setDescription(listDataObj.getDescription());
listData.get(currentPosition).setEndDate(listDataObj.getEndDate());
listData.get(currentPosition).setStartDate(listDataObj.getStartDate());
listData.get(currentPosition).setNamee(listDataObj.getNamee());
notifyDataSetChanged();
}
public interface OnEditListener{
void onEditClick(SubTrial listCurrentData, int CurrentPosition);
}
}
分段
import android.app.AlertDialog;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class SubscriptionFragment extends Fragment implements SubscriptionDialogFragment.OnInputSelected {
AlertDialog alertDialog;
TextView textView1;
RecyclerView subscriptionList;
private FloatingActionButton mOpenDialog;
SubTrialAdapter subscriptionAdapterList;
ArrayList<SubTrial> subTrialArrayList;
@Override
public void sendInput(String name, String startDate, String endDate, String description, String link) {
addSubscription(name, startDate, endDate, description, link);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_subscription, container, false);
mOpenDialog = view.findViewById(R.id.fabSub);
subTrialArrayList = new ArrayList<>();
subscriptionList = view.findViewById(R.id.activityListSub);
subscriptionList.setHasFixedSize(true);
subscriptionList.setLayoutManager(new LinearLayoutManager(this.getActivity(), LinearLayoutManager.VERTICAL, false));
textView1 = view.findViewById(R.id.textView1);
mOpenDialog.setOnClickListener(v -> {
SubscriptionDialogFragment dialog = new SubscriptionDialogFragment();
dialog.setTargetFragment(SubscriptionFragment.this, 1);
dialog.show(getFragmentManager(), "Dialog");
});
return view;
}
public void addSubscription(String strName, String strStartDate, String strEndDate, String strDescription, String strLink) {
textView1.setText(strStartDate);
SubTrial obj = new SubTrial();
obj.setNamee(strName);
obj.setStartDate(strStartDate);
obj.setEndDate(strEndDate);
obj.setDescription(strDescription);
obj.setLink(strLink);
subTrialArrayList.add(obj);
subscriptionAdapterList = new SubTrialAdapter(this.getContext(), subTrialArrayList, this::onEditClick);
subscriptionList.setAdapter(subscriptionAdapterList);
}
private void onEditClick(SubTrial listCurrentData, int currentPosition) {
View view=LayoutInflater.from(this.getContext()).inflate(R.layout.edit_subscription,null);
AlertDialog.Builder builderObj=new AlertDialog.Builder(view.getContext());
EditText mSubscriptionName = view.findViewById(R.id.subscriptionName);
EditText mStartDate = view.findViewById(R.id.startDate);
EditText mEndDate = view.findViewById(R.id.endDate);
EditText mDescription = view.findViewById(R.id.description);
EditText mLink = view.findViewById(R.id.link);
MaterialButton btnEdit=view.findViewById(R.id.btnEdit);
mSubscriptionName.setText(listCurrentData.getNamee());
mStartDate.setText(listCurrentData.getStartDate());
mEndDate.setText(listCurrentData.getEndDate());
mDescription.setText(listCurrentData.getDescription());
mLink.setText(listCurrentData.getLink());
ImageView closeAlert = view.findViewById(R.id.closeAlert);
builderObj.setView(view);
builderObj.setCancelable(false);
closeAlert.setOnClickListener(v -> {
alertDialog.cancel();
});
btnEdit.setOnClickListener(v->{
String strName = "", strStartDate = "", strEndDate = "", strDescription = "", strLink = "";
if (mSubscriptionName.getText() != null) {
strName = mSubscriptionName.getText().toString();
}
if (strName.equals("")) {
Toast.makeText(this.getContext(), "Please enter Subscription Name", Toast.LENGTH_LONG).show();
return;
}
if (mStartDate.getText() != null) {
strStartDate = mStartDate.getText().toString();
}
if (strStartDate.equals("")) {
Toast.makeText(this.getContext(), "Please enter Start Date", Toast.LENGTH_LONG).show();
return;
}
if (mEndDate.getText() != null) {
strEndDate = mEndDate.getText().toString();
}
if (strEndDate.equals("")) {
Toast.makeText(this.getContext(), "Please enter End Date", Toast.LENGTH_LONG).show();
return;
}
if (mDescription.getText() != null) {
strDescription= mDescription.getText().toString();
}
if (strDescription.equals("")) {
Toast.makeText(this.getContext(), "Please enter Description", Toast.LENGTH_LONG).show();
return;
}
if (mLink.getText() != null) {
strLink = mLink.getText().toString();
}
if (strLink.equals("")) {
Toast.makeText(this.getContext(), "Please enter Link", Toast.LENGTH_LONG).show();
return;
}
editContact(strName, strStartDate, strEndDate, strDescription, strLink, currentPosition);
});
alertDialog=builderObj.create();
alertDialog.show();
}
public void editContact(String strUserName, String strStartDate, String strEndDate, String strDescription, String strLink, int currentPosition){
SubTrial obj = new SubTrial();
obj.setNamee(strUserName);
obj.setStartDate(strStartDate);
obj.setEndDate(strEndDate);
obj.setDescription(strDescription);
obj.setLink(strLink);
subscriptionAdapterList.editData(obj,currentPosition);
alertDialog.cancel();
}
}
是的。 因為一旦您退出應用程序,應用程序內存就會在后台進程中被殺死,並且打開應用程序會創建一個新實例。 例如,您創建了一個 editText 和一個按鈕,該按鈕在單擊時顯示用戶向用戶輸入的 Toast + 文本。 應用程序內存將在您關閉后停止,一旦您將其從后台內存中刪除,它將關閉。 此方法稱為 onDestroy() 。
因此,為了防止這種情況,您可以使用 android 默認本地存儲,例如SQlite Database 、 Shared Preferences 、 Room Database
1. Sqlite數據庫是android的離線本地數據庫,不需要互聯網訪問來存儲數據。 並且要存儲在 SQlite 數據庫中的數據應該是字符串格式,如 uri 路徑。 不建議在 SQLite 數據庫中存儲更大的文件或內容,如圖像、音頻、視頻,以防止出現以下異常:
FATAL EXCEPTION: main
11-06 15:16:17.199: E/AndroidRuntime(1789): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.demodbimage/com.example.demodbimage.ImagesList}: java.lang.IllegalStateException: Couldn't read row 0, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
2. Shared Preferences 適合以字符串、布爾值、整數等鍵的形式存儲非常小的數據值。 例如,您希望在第一次登錄成功后阻止用戶登錄,或者您希望在用戶第一次選擇加入后下次顯示深色主題。
3. Room Database 和 Sqlite 數據庫一樣,但是 Google 推薦我們使用它,因為它易於使用,還提供數據庫語法,並且對錯誤非常敏感。
或者您可以使用在線數據庫,例如 mySQL、MongoDB、Firebase 數據庫、mariaDb 等。
基本上,RecyclerView 與 Room(本地數據庫)或 API(遠程數據庫,如 MySQL)等數據庫結合使用。
但是,如果您正在為您的投資組合創建一個非常輕量級的項目,我認為使用數據存儲或sharedPrefereces並不是一個壞主意。 與任何程序一樣,Kotlin 中常用的List和Array當然是易變的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.