Android - Как сохранить состояние моего логического значения ImageView для списка элементов ListView? - PullRequest
0 голосов
/ 28 октября 2018

Я впервые пытаюсь создать приложение, которое в основном представляет собой контрольный список, который помогает мне отслеживать то есть собранные элементы.Очень похоже на контрольный список в игре.Я не очень разбираюсь в Android, поэтому нашел какой-то шаблон, который я изменил для своих нужд.В основном я использую два .png файла (флажок и флажок) в качестве ImageView, которые при нажатии сменяют друг друга, имитируя основной флажок.По-видимому, этот метод работал лучше всего для меня, хотя я думал, что обычный объект-флажок будет проще.Когда я использовал обычные объекты-флажки, статус «флажок» перемещался по всему списку ... И с помощью этого метода ImageView флажки оставались такими же, как те, которые я действительно проверял.

Итак, я понял, как создатьСписок.Позже я вручную изменю список на Предметы / Имена / и т.д.как я хочу, это не будет проблемой.Приложение также позволяет мне выбрать несколько элементов, и элементы остаются отмеченными даже после включения.Проблема, с которой я сталкиваюсь сейчас, заключается в том, что после искажения приложения на устройстве и перезапуска приложения все отмеченные элементы теперь не проверяются.Это означает, что информация, которую проверял элемент, не была сохранена вообще.

Я был бы очень рад, если бы кто-нибудь мог помочь мне с завершением кода ... Я понятия не имею, как сохранить информацию о том, какой элемент в списке был проверен, и не говоря уже о перезагрузке при onCreate.

Вот activity_main.xml , который в основном является ListView.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="15dp"
    android:paddingTop="15dp"
    android:paddingStart="10dp"
    android:paddingEnd="10dp"
    tools:context="com.multiselect.MainActivity">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/listview"
        android:divider="@android:color/darker_gray"
        android:dividerHeight="2dp"/>

</RelativeLayout>

Далее следует list_view_item.xml где объявлены Name, Subtitle и Checkbox ImageView.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="60dp">

//NAME//
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv_user_name"
    android:gravity="center_vertical"
    android:layout_toEndOf="@+id/iv_check_box"
    android:paddingStart="10dp"
    android:textAppearance="?android:attr/textAppearanceLarge" />

//SUB
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tv_user_sub"
    android:layout_alignStart="@+id/tv_user_name"
    android:layout_below="@+id/tv_user_name"
    android:paddingStart="10dp"
    android:textColor="@color/sub"
    android:textAppearance="?android:attr/textAppearanceMedium"
    tools:ignore="RtlSymmetry" />

//Checkbox
<ImageView
    android:layout_width="20dp"
    android:layout_height="20dp"
    android:id="@+id/iv_check_box"
    android:layout_alignParentStart="true"
    android:onClick="onCheckboxClicked"
    android:layout_centerVertical="true"
    android:background="@drawable/check"/>

</RelativeLayout>

Итак, у меня есть базовый UserModel.java со всеми получателямии сеттеры.

package com.multiselect;

public class UserModel {

    private boolean isSelected;
    private String userName;
    private String userSub;

    //create constructor and getter setter


    public UserModel(boolean isSelected, String userName, String userSub) {
        this.isSelected = isSelected;
        this.userName = userName;
        this.userSub = userSub;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserSub() {
        return userSub;
    }

    public void setUserSub(String userSub) {
        this.userSub = userSub;
    }
}

Тогда я знаю, что мне нужно CustomAdapter.java для того, что я хочу сделать.У меня есть ViewHolder внутри вместе с программой обновления для элементов чекла.

    package com.multiselect;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;   
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class CustomAdapter extends BaseAdapter {

    Activity activity;
    List<UserModel> users;
    LayoutInflater inflater;


    //short to create constructer using alt+insert or rightclick - generate - constructor

    public CustomAdapter(Activity activity) {
        this.activity = activity;
    }

    public CustomAdapter(Activity activity, List<UserModel> users) {
        this.activity = activity;
        this.users = users;

        inflater = activity.getLayoutInflater();
    }

    @Override
    public int getCount() {
        return users.size();
    }

    @Override
    public Object getItem(int i) {
        return i;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;

        if(view == null){
            view = inflater.inflate(R.layout.list_view_item, viewGroup, false);
            holder = new ViewHolder();

            holder.tvUserName = (TextView)view.findViewById(R.id.tv_user_name);
            holder.tvUserSub = (TextView)view.findViewById(R.id.tv_user_sub);
            holder.ivCheckBox = (ImageView) view.findViewById(R.id.iv_check_box);

            view.setTag(holder);
        }else
            holder = (ViewHolder) view.getTag();

        UserModel model = users.get(i);

        holder.tvUserName.setText(model.getUserName());
        holder.tvUserSub.setText(model.getUserSub());

        if (model.isSelected()) {
                holder.ivCheckBox.setBackgroundResource(R.drawable.checked);
        }
        else
                holder.ivCheckBox.setBackgroundResource(R.drawable.check);

        return view;
    }

    public void updateRecords(List<UserModel> users) {
        this.users = users;

        notifyDataSetChanged();

    }

    class ViewHolder{

        TextView tvUserName;
        TextView tvUserSub;
        ImageView ivCheckBox;


    }
}

... и MainActivity.java :

package com.multiselect;

import android.app.Activity;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.content.SharedPreferences;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView listView = (ListView) findViewById(R.id.listview);

        final List<UserModel> users = new ArrayList<>();

        for(int i = 0; i<20; i++) {
            users.add(new UserModel(false, "Name "+(i), "Subtitle " + (i)));
        }


        final CustomAdapter adapter = new CustomAdapter(this, users);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {


                UserModel model = users.get(i);


                if (model.isSelected())
                    model.setSelected(false);

                else
                    model.setSelected(true);

                users.set(i, model);

                //now update adapter
                adapter.updateRecords(users);


            }

        });

    }

}

И теперь я знаю, что я должен использовать SharedPreferences в MainActivity.java , но я не знаю, как в этом конкретном примере ... Особенно, когда я пробую его с другимилюди говорили, что приложение просто падает, как только я что-то проверяю, или когда я просто пытаюсь запустить приложение.Я буквально не достаточно хорош для этого, и я действительно хочу знать, как что-то, что я обычно принимаю как должное (что приложение помнит, что в нем было надето), делается программно.

Я надеюсь, что кто-то может завершить мойКод, чтобы приложение запоминало, какой флажок был установлен, и перезагружало его при onCreate ...

1 Ответ

0 голосов
/ 28 октября 2018

Во-первых, вам нужно добавить уникальный атрибут в вашу модель пользователя.как userId

private int userId

, затем добавьте сеттеры и геттеры, как и другие атрибуты.Я думаю, что тогда вы можете использовать tinyDB для хранения недавних значений этого userId.Затем вы можете увеличивать этот userId при добавлении новой модели пользователя.

 TinyDB tinydb = new TinyDB(context);
 int recentid = tinydb.getInt(recentUserId) == null ? 0:tinydb.getInt(recentUserId)
 tinydb.putInt("recentUserId",recentid++);
 userModel1.setUserId(recentid)

После этого Вы можете создать список массивов с проверенными идентификаторами.Если пользователь проверил какой-либо пост, обновите этот список.Если пользователь отключил этот список, удалите его из списка.

 List<int> checkedList = new ArrayList<>;
    checkedList.add(..userid);

Затем вы можете обновить TinyDb при обновлении этого проверенного списка с помощью следующей команды.

tinydb.putList("checkedIdList", chekcedList);

, когда вам нужно состояние запуска приложениячтобы вызвать этот tinydb и получить проверенный список, используя приведенную ниже команду

  tinydb.getList("checkedIdList");

, тогда вы можете обновить свой список с проверенными и непроверенными состояниями

PS: вы можете перейти на https://github.com/kcochibili/TinyDB--Android-Shared-Preferences-Turbo thisи получить представление о tinydb.Это хорошее улучшение общих настроек


В методе onCrete необходимо выполнить следующие действия, чтобы избежать постоянного обновления checkList.

  List<int> checkedList = new ArrayList<>;

  if(tinydb.getList("checkedIdList")!= null){
      checkedList = tinydb.getList("checkedIdList")
  }
...