【问题标题】:How to Show Preload data to RecyclerView using Realm如何使用 Realm 向 RecyclerView 显示预加载数据
【发布时间】:2017-08-04 11:55:03
【问题描述】:

在我的应用程序中,我使用 Realm 作为本地数据库。我正在使用 recyclerview 小部件来显示这些数据。现在 initiallay 我想在回收器视图中显示一些预加载数据,这些数据也将存储在领域中。然后我将实现添加、编辑、删除方法。但是我在尝试运行这个应用程序时遇到了致命错误。我是 Realm 的新手。我无法确定这是哪个问题。

我已经在答案代码的帮助下解决了这个问题。这是解决此问题的方法。

已解决的代码

我的活动课是

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);

 }

.....

【问题讨论】:

  • 你使用的是什么版本的 Realm?

标签: android realm fatal-error android-recyclerview


【解决方案1】:

解决眼前的问题

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);

应该是

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);

但是基于Prefs.with(this).preload(),您的代码基于 Ravi Tamada 的教程,该教程充满了可怕的做法,我认为它仍然是 Realm 0.82.2。

不要忘记最新版本的 Realm(在撰写本文时)是 Realm 3.5.0,最好使用 official documentation

例如,您应该使用realm-android-adapters(官方插件)提供的RealmRecyclerViewAdapter,而不是使用您自己的。


编辑:这是完整的解决方案

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);
                }
            });
        }
 }

【讨论】:

  • 感谢您的代码。是的,我根据 Ravi Tamada 的教程示例编写代码。我在android开发方面还是很新的。因此,我用领域实现 recyclerview 太复杂了。我已经阅读了很多文章,但没有详细解释。我仍然对使用 Realm 实现 recyclerview 感到困惑。特别是适配器类。
  • 你需要使用github.com/realm/realm-android-adapters中的RealmRecyclerViewAdapter并删除你当前拥有的大约一半的代码(尤其是你拥有的List字段,并用getData()updateData()替换它)
  • 我已经更新了我的代码。请看看我的代码。我使用了 RecyclerView.Adapter。但这也有效。问题在于此代码在添加新信息后数据未更新。如果我单击另一个选项,则它会更新。如果你看看我的代码,那就太好了
  • 你能告诉我如何使用我们的 prefis 类显示预加载数据
  • 非常感谢您的代码。我创建了新问题。因为在这个问题中,显示一些预加载数据是主要问题。你的回答解决了这个问题。如果你不介意可以看看我的新问题stackoverflow.com/questions/45542960/…
【解决方案2】:

setRealmData() 方法中为model.setId(); 设置唯一值,它会起作用,

您正在尝试设置已经存在的主键值。

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);
    }

在领域 ref this SO 答案中创建自动增量

【讨论】:

  • 您能否再解释一下。我是发展中国家的新手
  • No in setRealmData() 你正在做 model.setId(1 + System.currentTimeMillis()); 在你正在做的那个方法中搜索 model.setId 在 3 个地方
  • 你在该方法中有 3 个位置
  • 我写了一些长数字 123466。但仍然有同样的错误
  • 不,不要那样做,不应该重复,那就是错误,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多