How to Show Preload data to RecyclerView using Rea

2019-02-20 18:07发布

问题:

In my App I am using Realm as local database. I am using recyclerview widget to show these data. Now initiallay I want to show some preload data in recycler view which would be stored in realm as well. then I will implement add, edit, delete method. But I am having fatal error while trying to run this app. I am very new in Realm. I cannot identify which problem is this.

I have Solved this problem with the help of answer code. here is the solution for this.

Solved Code

And My Activity Class is

public class MyColleaguesPage extends AppCompatActivity {

private RecyclerView recyclerView;
private MyColleaguesAdapter adapter;
private Realm colleagueRealm;
private List<MyColleagueModel> colleagueObject;
private RealmResults<MyColleagueModel> dataResult;
private static final String DIALOG_TAG = "EmployeeDialog";

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

    colleagueRealm = Realm.getDefaultInstance();
    recyclerView = (RecyclerView) findViewById(R.id.colleagues_recycler);

    setUpRecycler();

    if (!Prefs.with(this).getPreLoad()) {
        setRealmData();
    }
    showAllPersons();

 }

private void showAllPersons() {
    dataResult = colleagueRealm.where(MyColleagueModel.class).findAll();
    setAdapter(dataResult);
    adapter.notifyDataSetChanged();
 }
//find all objects in the Book.class
private void setAdapter(RealmResults<MyColleagueModel> results) {
    adapter = new MyColleaguesAdapter(this, results);
    recyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();

}
private void setUpRecycler() {

    recyclerView.setHasFixedSize(true);
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);
}

private void setRealmData(){

    List<MyColleagueModel> colleague = new ArrayList<>();
    MyColleagueModel model = new MyColleagueModel();
    model.setId(1 + System.currentTimeMillis());
    model.setName("Name1");
    model.setCompany("Comapny1");
    model.setTitle("Title1");
    colleague.add(model);

    model = new MyColleagueModel();
    model.setId(2 + System.currentTimeMillis());
    model.setName("Name2");
    model.setCompany("Comapny2");
    model.setTitle("Title1");
    colleague.add(model);

    model = new MyColleagueModel();
    model.setId(3 + System.currentTimeMillis());
    model.setName("Name3");
    model.setCompany("Comapny3");
    model.setTitle("Title3");
    colleague.add(model);


    for (MyColleagueModel realmModel : colleague) {
            // Persist the colleague data
            colleagueRealm.beginTransaction();
            colleagueRealm.copyToRealm(realmModel);
            colleagueRealm.commitTransaction();
    }

    Prefs.with(this).setPreLoad(true);

 }

.....

回答1:

To fix immediate problem

private void setRealmData(){
    List<MyColleagueModel> colleague = new ArrayList<>();

    MyColleagueModel model = new MyColleagueModel();
    model.setId(1 + System.currentTimeMillis());
    model.setName("Name1");
    model.setCompany("Comapny1");
    model.setTitle("Title1");
    colleague.add(model);

    model.setId(2 + System.currentTimeMillis());
    model.setName("Name2");
    model.setCompany("Comapny2");
    model.setTitle("Title1");
    colleague.add(model);

    model.setId(3 + System.currentTimeMillis());
    model.setName("Name3");
    model.setCompany("Comapny3");
    model.setTitle("Title3");
    colleague.add(model);

should be

private void setRealmData(){
    List<MyColleagueModel> colleague = new ArrayList<>();

    MyColleagueModel model = new MyColleagueModel();
    model.setId(1 + System.currentTimeMillis());
    model.setName("Name1");
    model.setCompany("Comapny1");
    model.setTitle("Title1");
    colleague.add(model);

    model = new MyColleagueModel();
    model.setId(2 + System.currentTimeMillis());
    model.setName("Name2");
    model.setCompany("Comapny2");
    model.setTitle("Title1");
    colleague.add(model);

    model = new MyColleagueModel();
    model.setId(3 + System.currentTimeMillis());
    model.setName("Name3");
    model.setCompany("Comapny3");
    model.setTitle("Title3");
    colleague.add(model);

But based on Prefs.with(this).preload() you are basing your code on Ravi Tamada's tutorial which is full of terrible practices and I think it's still Realm 0.82.2.

Don't forget that latest version of Realm (at time of writing) is Realm 3.5.0, and you are better off with the official documentation.

For example, you should use RealmRecyclerViewAdapter provided by realm-android-adapters (official add-on) instead of using your own.


EDIT: Here is full solution

public class MyColleaguesPage extends AppCompatActivity implements ColleagueListListener {

    private Realm realm;
    private RecyclerView recyclerView;
    private MyColleaguesAdapter adapter;

    private static final String DIALOG_TAG = "EmployeeDialog";

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

        // Showing and Enabling clicks on the Home/Up button
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        }
        realm = Realm.getDefaultInstance();
        recyclerView = (RecyclerView) findViewById(R.id.colleagues_recycler);

        recyclerView.setHasFixedSize(true);
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new MyColleaguesAdapter(this, realm.where(MyColleagueModel.class).findAllSortedAsync("id"));
        recyclerView.setAdapter(adapter);
     }

     @Override
     protected void onDestroy() {
        super.onDestroy();
        realm.close();
        realm = null;
     }
}        

public class InitialData implements Realm.Transaction {
    @Override
    public void execute(Realm realm) {
        List<MyColleagueModel> colleague = new ArrayList<>();
        MyColleagueModel model = new MyColleagueModel();
        model.setId(1 + System.currentTimeMillis());
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        colleague.add(model);

        model = new MyColleagueModel();
        model.setId(2 + System.currentTimeMillis());
        model.setName("Name2");
        model.setCompany("Comapny2");
        model.setTitle("Title1");
        colleague.add(model);

        model = new MyColleagueModel();
        model.setId(3 + System.currentTimeMillis());
        model.setName("Name3");
        model.setCompany("Comapny3");
        model.setTitle("Title3");
        colleague.add(model);


        for (MyColleagueModel realmModel : colleague) {
            realm.insertOrUpdate(realmModel);
        }
    }

    @Override
    public boolean equals(Object obj) {
        return obj != null && obj instanceof InitialData;
    }

    @Override
    public int hashCode() {
        return InitialData.class.hashCode();
    }
}

public class CustomApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Realm.init(this);
        Realm.setDefaultConfiguration(new RealmConfiguration.Builder()
                      .deleteIfMigrationNeeded()
                      .initialData(new InitialData())
                      .build());
    }
}

<application name=".CustomApplication"
             .../>

public class MyColleaguesAdapter extends RealmRecyclerViewAdapter<MyColleagueModel, MyColleaguesAdapter.ColleagueHolder> {   
    public interface ColleagueListListener {
        void addPerson(MyColleagueModel colleagueModel);
        void editPerson(MyColleagueModel colleagueModel);
    }

    private final ColleagueListListener colleagueListListener;

    public MyColleaguesAdapter(ColleagueListListener colleagueListListener, RealmResults<MyColleagueModel> results) {
        super(results, true);
        this.colleagueListListener = colleagueListListener;
    }

    @Override
    public ColleagueHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ColleagueHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.colleage_row_layout,parent,false));
    }

    @Override
    public void onBindViewHolder(ColleagueHolder holder, int position) {
        final MyColleagueModel myColleague = getData().get(position);
        holder.bind(myColleague);
    }

    public class ColleagueHolder extends RecyclerView.ViewHolder {

        public CardView cardView;
        public ImageView colleaguePicture;
        public TextView  colleagueName;
        public TextView  companyName;
        public TextView  jobTitle;

        public ColleagueHolder(View itemView) {
            super(itemView);
            //colleaguePicture=(ImageView)itemView.findViewById(R.drawable.profile_image);
            colleagueName=(TextView)itemView.findViewById(R.id.colleague_name);
            companyName=(TextView) itemView.findViewById(R.id.company_name);
            jobTitle=(TextView) itemView.findViewById(R.id.job_title);
            cardView=(CardView)itemView.findViewById(R.id.cardview_user);
          }
        }

        public void bind(MyColleagueModel myColleague) {
            holder.colleagueName.setText(myColleague.getName());
            holder.companyName.setText(myColleague.getCompany());
            holder.jobTitle.setText(myColleague.getTitle());
            holder.cardView.setTag(position);
            holder.cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    colleagueListListener.editPerson(myColleague);
                }
            });
        }
 }


回答2:

set unique value to model.setId(); in setRealmData() method, it will work,

You are trying set the primary key value which alreay exits.

private void setRealmData(){
        List<MyColleagueModel> colleague = new ArrayList<>();

        int id;
        try {
           id = 
colleagueRealm.where(MyColleagueModel.class).max("id").intValue() + 1;
        } catch(ArrayIndexOutOfBoundsException ex) {
           id = 0; // when there is no object in the database yet
        }
        MyColleagueModel model = new MyColleagueModel();
        model.setId(1 + id);
        model.setName("Name1");
        model.setCompany("Comapny1");
        model.setTitle("Title1");
        colleague.add(model);

        model.setId(2 + id);
        model.setName("Name2");
        model.setCompany("Comapny2");
        model.setTitle("Title1");
        colleague.add(model);

        model.setId(3 + id);
        model.setName("Name3");
        model.setCompany("Comapny3");
        model.setTitle("Title3");
        colleague.add(model);

        for (MyColleagueModel realmModel : colleague) {
            // Persist the colleague data
            colleagueRealm.beginTransaction();
            colleagueRealm.copyToRealm(realmModel);
            colleagueRealm.commitTransaction();
        }

        Prefs.with(this).setPreLoad(true);
    }

Create auto increment in realm ref this SO answer