【问题标题】:RecyclerView don't show inserted SQLite data instantlyRecyclerView 不会立即显示插入的 SQLite 数据
【发布时间】:2016-03-07 18:01:57
【问题描述】:

当来自FragmentDialog 的用户在编辑文本中输入他的数据并按下保存按钮时,数据应该立即显示在recyclerView 中,但这并没有发生。要获取/显示最新数据,您必须重启应用

我使用了一个临时解决方案,通过接口将数据从FragmentDialog 传递到mainActivity,然后直接将该数据传递到recyclerView 的arraylist 中。这项工作,但看起来不像一个适当的解决方案。我希望有一个“正确”的方式来做到这一点

我也尝试过设置 adapter.notifyDataSetChanged();不同的地方没有任何成功

DialogFragment 类,用户在其中键入他的数据,然后插入到 SQLite 数据库中

public class DialogAdd extends DialogFragment {

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    final View rootView = inflater.inflate(R.layout.add_productdialog,container, false);



    name = (EditText) rootView.findViewById(R.id.dialog_productname);
    quantity = (EditText) rootView.findViewById(R.id.dialog_qantity);
    location = (EditText) rootView.findViewById(R.id.dialog_location);
    normalPrice = (EditText) rootView.findViewById(R.id.dialog_normalPrice);
    offerPrice = (EditText) rootView.findViewById(R.id.dialog_offerPrice);

    okButton = (Button) rootView.findViewById(R.id.dialog_okButton);
    okButton.getBackground().setColorFilter(Color.parseColor("#2fbd4b"), PorterDuff.Mode.MULTIPLY);
    okButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {


            if (name.getText().toString().isEmpty()) {
                Toast.makeText(context, "You must add a name", Toast.LENGTH_LONG).show();
            } else {


                DialogAddListener addListener = (DialogAddListener) getActivity();

                dbHelper.insertData(name.getText().toString(), quantity.getText().toString(), location.getText().toString(), normalPrice.getText().toString(), offerPrice.getText().toString());
                addListener.getDialogData(name.getText().toString(), quantity.getText().toString(), location.getText().toString(), normalPrice.getText().toString(), offerPrice.getText().toString());


                getDialog().dismiss();
            }


        }
    });

    return rootView;

}

实例化recyclerview、sqlite和适配器的mainActivity类

public class MainActivity extends AppCompatActivity implements DialogAdd.DialogAddListener{



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



    databaseHelper = new DatabaseHelper(this);

    addbutton = (ImageButton) findViewById(R.id.addbtn);
    addbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialogAdd = new DialogAdd();
            dialogAdd.show(getSupportFragmentManager(), "addDialog");
        }
    });



    //RecyclerView
    recyclerView = (RecyclerView)findViewById(R.id.rv_shoppinglist);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(App.getAppContex());
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(linearLayoutManager);



    initializeData();
    adapter = new ShoplistAdapter(shopListItems);
    recyclerView.setAdapter(adapter);
    adapter.notifyDataSetChanged();

}



private void initializeData(){

    shopListItems = new ArrayList<>();
    resultset = databaseHelper.getAllData();

    if (resultset.moveToFirst()){
        while(!resultset.isAfterLast()){
            shopListItems.add(new ShopListItem(resultset.getString(1), resultset.getString(2), resultset.getString(3), resultset.getString(4), resultset.getString(5)));
            resultset.moveToNext();

            totalPrice.setText("Total cost: $" + "26");
            totalItems.setText("Total items: " + resultset.getCount());
        }
    }
    resultset.close();
}


//This is only used to show the data instantly
@Override
public void getDialogData(String name, String qty, String location, String price1, String price2) {
    shopListItems.add(new ShopListItem(name, qty, location, price1, price2));
}

}

【问题讨论】:

    标签: android sqlite android-recyclerview


    【解决方案1】:

    您应该使用CursorLoader,它会自动侦听Uri 中的更改。并通过contentResolver.notifyChanged(uriOfInsertedData) 通知更改。最糟糕的方法是使用ContentProvider 让所有的东西都能正常工作。

    或者为了更简单的方法,为您的数据库在单例中注册一个观察者并在更改时通知它。一般来说,这会做同样的事情,并且组件之间不会有任何关系。需要一些代码才能发布,所以我希望你能弄清楚。

    更新 2016-03-09,根据您的评论

    如果您实施了示例 1,它不会告诉您如何监控更改。这种情况没有现成的机制。

    实现这种机制的最佳方法是使用观察者模式。

    我会选择一个托管观察者的单身人士。

    您可以扩展 Observable(它已经具有存储观察者列表、通知和删除它们的逻辑)并使其成为单例。

    在您需要收听的任何地方调用addObserver() 注册观察者(不要忘记调用deleteObserver() 以避免活动泄漏)。

    现在,每当您调用 insert 或以任何方式修改数据库时,请确保调用 notifyObservers("tablename") of Observable 单例。

    这样所有的观察者都会收到表被修改的通知(传递一个表名就是一个例子,你可以使用那里的任何对象来通知你的组件有关更改)

    然后在您的Observer 中的update() 中,检查您要监控的表是否已更新,如果是,请照常重新加载数据。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多