Android studio: Как обновить текстовое представление в программе просмотра отходов при удалении элемента из базы данных? - PullRequest
1 голос
/ 05 января 2020

Итак, я сделал демонстрационное приложение, чтобы продемонстрировать свою проблему и получить несколько картинок для ожидаемого результата. Я использую Room для создания базы данных, и пользователь может добавить запись, нажав кнопку. Есть только два поля: идентификатор (первичный ключ) и номер строки. Я установил номер строки, получив количество записей в запросе и добавив один к этому значению. Затем я вставляю новую запись с конструктором, требующим номер строки.

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

Я добавил 10 строк на первом рисунке, удалил несколько строк на втором, а третий показывает, что Я хочу, чтобы результат был за вычетом краски:

10 rows added

enter image description here

enter image description here

Вот код:

MainActivity. Java

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private TestViewModel testViewModel;

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



        Button addButton = findViewById(R.id.test_button);
        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        final TestAdapter adapter = new TestAdapter();
        recyclerView.setAdapter(adapter);

        testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
        testViewModel.getAllTests().observe(this, new Observer<List<Test>>() {
            @Override
            public void onChanged(List<Test> tests) {
                adapter.submitList(tests);
            }
        });

        testViewModel.getNumberOfEntries().observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {

            }
        });

        new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
                ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                testViewModel.delete(adapter.getTestAt(viewHolder.getAdapterPosition()));
            }
        }).attachToRecyclerView(recyclerView);

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (testViewModel.getNumberOfEntries().getValue() != null) {
                    int rowNum = testViewModel.getNumberOfEntries().getValue() + 1;
                    testViewModel.insert(new Test(rowNum));
                }else{
                    int rowNum = 1;
                    testViewModel.insert(new Test(rowNum));
                }
            }
        });
    }


}


Test. Java


import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity(tableName = "test_table")
public class Test {

    @PrimaryKey(autoGenerate = true)
    private int id;

    private int rowNumber;

    public Test(int rowNumber){
        this.rowNumber = rowNumber;
    }

    public int getId() {
        return id;
    }

    public int getRowNumber() {
        return rowNumber;
    }

    public void setId(int id) {
        this.id = id;
    }
}

TestAdapter. Java

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class TestAdapter extends ListAdapter <Test, TestAdapter.TestHolder> {

    protected TestAdapter() { super(DIFF_CALLBACK); }

    private static final DiffUtil.ItemCallback<Test> DIFF_CALLBACK = new DiffUtil.ItemCallback<Test>() {
        @Override
        public boolean areItemsTheSame(@NonNull Test oldItem, @NonNull Test newItem) {
            return newItem.getId() == oldItem.getId();
        }

        @Override
        public boolean areContentsTheSame(@NonNull Test oldItem, @NonNull Test newItem) {
            return newItem.getRowNumber() == oldItem.getRowNumber();
        }
    };

    @NonNull
    @Override
    public TestHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.test_item, parent, false);
        return new TestHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull TestAdapter.TestHolder holder, int position) {
        Test currentTest = getItem(position);

        holder.textViewRowNumber.setText(String.valueOf(currentTest.getRowNumber()));
    }

    public Test getTestAt(int position){ return  getItem(position);}

    class TestHolder extends RecyclerView.ViewHolder{
        private TextView textViewRowNumber;

        public TestHolder(View itemView){
            super(itemView);
            textViewRowNumber = itemView.findViewById(R.id.test_text_view);
        }
    }
}

TestDao. Java

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;

import java.util.List;

@Dao
public interface TestDao {

    @Insert
    void insert(Test test);

    @Delete
    void delete(Test test);

    @Query("SELECT * FROM test_table")
    LiveData<List<Test>> getAllEntries();

    @Query("SELECT Count(*) FROM test_table")
    LiveData<Integer>getNumberOfEntries();
}

TestDatabase. Java

import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;

@Database(entities = Test.class, version = 1)

public abstract class TestDatabase extends RoomDatabase {

    private static TestDatabase instance;

    public abstract TestDao testDao();

    public static synchronized TestDatabase getInstance(Context context){
        if(instance == null){
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    TestDatabase.class, "test_database")
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return instance;
    }
}

TestRepository. Java

import android.app.Application;
import android.os.AsyncTask;

import androidx.lifecycle.LiveData;

import java.util.List;

public class TestRepository {
    private TestDao testDao;
    private LiveData<List<Test>> allTests;
    private LiveData<Integer> numberOfEntries;

    public TestRepository(Application application) {
        TestDatabase database = TestDatabase.getInstance(application);
        testDao = database.testDao();
        allTests = testDao.getAllEntries();
        numberOfEntries = testDao.getNumberOfEntries();
    }

    public void insert(Test test) {
        new InsertTestAsyncTask(testDao).execute(test);
    }

    public void delete(Test test) {
        new DeleteTestAsyncTask(testDao).execute(test);
    }

    public LiveData<Integer> getNumberOfEntries() {
        return numberOfEntries;
    }

    public LiveData<List<Test>> getAllTests() {
        return allTests;
    }

    private static class InsertTestAsyncTask extends AsyncTask<Test, Void, Void> {
        private TestDao testDao;

        private InsertTestAsyncTask(TestDao testDao) {
            this.testDao = testDao;
        }

        @Override
        protected Void doInBackground(Test... tests) {
            testDao.insert(tests[0]);
            return null;
        }
    }

    private static class DeleteTestAsyncTask extends AsyncTask<Test, Void, Void> {
        private TestDao testDao;

        private DeleteTestAsyncTask(TestDao testDao) {
            this.testDao = testDao;
        }

        @Override
        protected Void doInBackground(Test... tests) {
            testDao.delete(tests[0]);
            return null;
        }
    }

}

TestViewModel. Java

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;

import java.util.List;

public class TestViewModel extends AndroidViewModel {
    private TestRepository repository;
    private LiveData<Integer> numberOfEntries;
    private LiveData<List<Test>> allTests;

    public TestViewModel(@NonNull Application application) {
        super(application);
        repository = new TestRepository(application);
        numberOfEntries = repository.getNumberOfEntries();
        allTests = repository.getAllTests();
    }

    public void insert(Test test) { repository.insert(test);}

    public void delete(Test test) { repository.delete(test);}

    public LiveData<Integer> getNumberOfEntries(){ return numberOfEntries; }

    public LiveData<List<Test>> getAllTests() { return allTests;}
}

Спасибо!

Ответы [ 2 ]

0 голосов
/ 05 января 2020

Попробуйте изменить реализацию ItemTouchHelper, как показано ниже:

new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,
        ItemTouchHelper.RIGHT) {
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        testViewModel.delete(adapter.getTestAt(viewHolder.getAdapterPosition()));

        //get current list from adapter
        List currentList = adapter.getCurrentList();

        //remove item from list 
        currentList.remove(viewHolder.getAdapterPosition());

        //submit the current list to refresh view
        adapter.submitList(currentList);
    }
}).attachToRecyclerView(recyclerView);
0 голосов
/ 05 января 2020

Выполните следующие действия, надеюсь, это поможет:

  1. получите itemList от TestAdapter.

  2. , которые вы можете изменить любое сырье, которое вы хотите. (Например, изменить данные элемента в необработанном виде 6)

  3. отправить их обратно на testAdapter.

  4. метод вызова notifyDataSetChanged();.

  5. если вы меняете только один элемент за раз, лучше позвонить notifyItemChanged(position);, потому что он имеет лучшую производительность, чем notifyDataSetChanged();

У вас есть другие инструменты, такие как notifyItemInserted(position); notifyItemRemoved(position);, которые могут вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...