简体   繁体   中英

Update RecyclerView view after adding a new item to room database

I'm making calculator app on android. I have two pages, calculator page and history page. The application saves math operations, results and operating times in room database. I would like the app to show these three entities in history page after pressing "equals" button.

Now my calculator app shows the entities after closing it. How can I fix/change this? I have tried notifyDataSetChanged() in many ways but it didn't work. Sometimes it stopped showing any data in history page.

Feel free to ask if you need more information or you didn't understand me. My English isn't the best. :D

Adapter:

package com.example.simplecalculator;
import android.annotation.SuppressLint;
import android.os.Bundle;
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.List;


public class CalculatorListAdapter extends 
RecyclerView.Adapter<CalculatorListAdapter.ViewHolder> {
public CalculatorListAdapter() {
}

public List<CalculationEntities> localDataset;


public CalculatorListAdapter(List<CalculationEntities> dataset) {
    localDataset = dataset;

}

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


@Override
public void onBindViewHolder(@NonNull CalculatorListAdapter.ViewHolder holder, int 
position) {
    holder.itemView.setTag(position);

    holder.tvCalculation.setText(localDataset.get(position).calculation);
    holder.tvResult.setText(localDataset.get(position).result);
    holder.tvTimeStamp.setText(localDataset.get(position).timeStamp);
}


@Override
public int getItemCount() {
    return localDataset.size();
}

public static class ViewHolder extends RecyclerView.ViewHolder {
    public final TextView tvResult;
    public final TextView tvCalculation;
    public final TextView tvTimeStamp;


    public ViewHolder(View itemView) {
        super(itemView);

        tvCalculation = (TextView) itemView.findViewById(R.id.tvOperation);
        tvResult = (TextView) itemView.findViewById(R.id.tvResult);
        tvTimeStamp = (TextView) itemView.findViewById(R.id.tvTimeStamp);
    }
}

}

History Fragment:

package com.example.simplecalculator;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.RoomDatabase;

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

import java.util.Arrays;
import java.util.List;


public class History extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_history, container, false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    RecyclerView rvHistory = view.findViewById(R.id.rvCalculationHistory);
    List<CalculationEntities> dataset = Arrays.asList(Calculator.database.CalculatorDao().getAllCalculations());

    CalculatorListAdapter calculatorListAdapter = new CalculatorListAdapter(dataset);
    rvHistory.setAdapter(calculatorListAdapter);
    rvHistory.setLayoutManager(new LinearLayoutManager(getContext()));

    super.onViewCreated(view, savedInstanceState);
}

}

DAO:

package com.example.simplecalculator;

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;

@Dao
public interface CalculatorDao {

    @Query("SELECT * FROM CalculationEntities WHERE calculation LIKE :name LIMIT 1")
    CalculationEntities findByName(String name);

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(CalculationEntities... calculations);

    @Query("SELECT * FROM CalculationEntities")
    CalculationEntities[] getAllCalculations();

    @Query("DELETE FROM CalculationEntities")
    void deleteAll();

}

Entities:

package com.example.simplecalculator;

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

@Entity
public class CalculationEntities {

@PrimaryKey(autoGenerate = true)
public int CalculationID;

@ColumnInfo(name="calculation")
public String calculation;

@ColumnInfo(name="result")
public String result;

@ColumnInfo(name="timeStamp")
public String timeStamp;

}

package com.example.simplecalculator;

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

@Database(entities = {CalculationEntities.class}, version = 1)
public abstract class CalculatorDatabase extends RoomDatabase {
    public abstract CalculatorDao CalculatorDao();

}

UPDATE: Still not working :/

UPDATE: localdataset increases after inserting data to database, but recyclerview won't update...

It would be best if you used LiveData for live query updates. As you are using Room, LiveData has a great extension for it. eg

LiveData is more professional but you can solve this problem by making the function reload data in fragment CalculatorListAdapter like:

1- create Function :

 public void ReloadData(){ localDataset = Arrays.asList(Calculator.database.CalculatorDao().getAllCalculations()); //Data now loaded }

2- Make data load at the constructor :

 public CalculatorListAdapter() { ReloadData(); }

3- Remove load data from the fragment history to be

 @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { RecyclerView rvHistory = view.findViewById(R.id.rvCalculationHistory); //Data will loaded auto at constructor CalculatorListAdapter calculatorListAdapter = new CalculatorListAdapter(); rvHistory.setAdapter(calculatorListAdapter); rvHistory.setLayoutManager(new LinearLayoutManager(getContext())); super.onViewCreated(view, savedInstanceState); }
4- At button pressing "equals" put function ReloadData() like you make in constructor and don't forget put notifyDataSetChanged()

History class:

    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    CalculatorListAdapter calculatorListAdapter = new CalculatorListAdapter();
    calculatorListAdapter.notifyDataSetChanged();

    RecyclerView rvHistory = view.findViewById(R.id.rvCalculationHistory);
    rvHistory.setAdapter(calculatorListAdapter);
    rvHistory.setLayoutManager(new LinearLayoutManager(getContext()));

    super.onViewCreated(view, savedInstanceState);
}

Adapter class:

public CalculatorListAdapter() {
    ReloadData();

}


public void ReloadData(){
    localDataset = Calculator.database.CalculatorDao().getAllCalculations();
    this.notifyDataSetChanged();
}

Equal button:

        else if (id == R.id.btnEqual) {

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM HH:mm");
        Equals equals = new Equals(output.getText().toString(), simpleDateFormat.format(calendar.getTime()));

        equals.isEqualTo();
        InitiateCalculation(equals.operation,equals.result,equals.operationTime);

        CalculatorListAdapter calculatorListAdapter = new CalculatorListAdapter();
        calculatorListAdapter.ReloadData();
        calculatorListAdapter.notifyDataSetChanged();

        output.setText(null);
        output.setText(equals.result);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM