【问题标题】:Updating Recycler Listview dynamically using Database使用数据库动态更新回收站列表视图
【发布时间】:2015-12-13 07:58:34
【问题描述】:

我看到了所有与我的问题相似的问题(thisthisthisthis 链接)

我的 Activity 中有 myAdapter.notifyDataSetChanged() 但它不起作用

我有 3 节课,

  • DBHelper - 用于存储和获取数据库内容(这里没有问题)
  • SimpleRecyclerAdapter - RecyclerList 的适配器
  • 第三个活动

我在 ThirdActivity 中做了什么:

我有 TextBox 来获取数据并将其存储在数据库和按钮中。在 Button的Onclicklistener,我指定了代码

  • 从文本框中获取文本
  • 使用 DBHelper 将其添加到表中
  • 从 DBHelper 以 ArrayList 形式检索数据
  • myAdapter.notifyDataSetChanged()

当我单击按钮时,我在 LogCat 中获得了数据,这是我在 OnclickListener 中指定的,但它没有反映到列表视图中。

这是我的代码,

第三个活动:

public class ThirdActivity extends AppCompatActivity{

    private DrawerLayout mDrawerLayout;
    DbHelper dbHelper;

    EditText et;
    Button addButton;
    RecyclerView rv;
    ArrayList<String> myNotesList;
    SimpleRecycler3Adapter adapter3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.thirdactivity);
        myNotesList = new ArrayList<>();
        et=(EditText) findViewById(R.id.et);
        addButton=(Button)findViewById(R.id.addButton);
        rv = (RecyclerView) findViewById(R.id.dbListrv);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getBaseContext());
        rv.setLayoutManager(linearLayoutManager);
        rv.setHasFixedSize(true);

        adapter3 = new SimpleRecycler3Adapter(myNotesList);
        rv.setAdapter(adapter3);
        dbHelper = new DbHelper(this, null, null, 1);


        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("DB", "Constructor");
              String note=et.getText().toString();
             dbHelper.addNote(note);
               printData();
            }
        });
    }

    public void printData(){
        Log.d("DB","Constructor");
        myNotesList=dbHelper.databasetostring();
        Log.d("DB","Data came"+myNotesList.get(myNotesList.size()-1));
     //  adapter3 = new SimpleRecycler3Adapter(myNotesList);
       // rv.setAdapter(adapter3);
        adapter3.notifyDataSetChanged();
    }
}

SimpleRecyclerViewAdapter:

public class SimpleRecycler3Adapter extends RecyclerView.Adapter<SimpleRecycler3Adapter.NotesHolder> {

private  ArrayList<String> myNotesList=new ArrayList<String>();

        String TAG="ThirdAdapter kbt";
        RecyclerView rv;

    public SimpleRecycler3Adapter(ArrayList<String> myList) {
        Log.d(TAG,"Constructor");

            Log.d(TAG,"Not null");
            int i = 0;
            while (i < myNotesList.size()) {
                myNotesList.add(myList.get(i).toString());
            }
            Log.d(TAG,"finish");
    }


    @Override
        public NotesHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
          Log.d(TAG,"On create started");
        View view2 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recyclerlist3_item, viewGroup, false);
        Log.d(TAG,"ADAP STAR ONCR second switch 2nd line");
        NotesHolder viewHolder2 = new NotesHolder(view2);
        Log.d(TAG,"ADAP STAR ONCR second switch 3nd line");
        return viewHolder2;
        }

@Override
public void onBindViewHolder(NotesHolder notesHolder, int i) {
        Log.d(TAG, "ONBIND SECOND i value is " + i);


        // notesHolder.thumbnail.setImageResource(R.drawable.placeholder);

        notesHolder.dblistitem.setText(myNotesList.get(i));
          Log.d(TAG,"ONBIND second title issssss");


        }


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

class NotesHolder extends RecyclerView.ViewHolder {

    protected ImageView thumbnail;
    protected TextView dblistitem;
    public NotesHolder(View itemView) {
        super(itemView);
        Log.d(TAG, "JSON Inside HOLDER");
        rv=(RecyclerView)itemView.findViewById(R.id.dbListrv);
      //  thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
        dblistitem = (TextView) itemView.findViewById(R.id.dblistitem);


    }

}

}

【问题讨论】:

  • 您在哪里从 DBHelper 检索数据作为 ArrayList?为什么要使用 myNotesList 2 次?
  • 在第三个 Activity 中,在这一行的 printData() 方法中 `myNotesList=dbHelper.databasetostring();` 在 Button Click Listener 中调用 printData() 方法
  • 你能更改私有 ArrayList myNotesList=new ArrayList() => private ArrayList myNotesList2=new ArrayList() 吗?
  • @tiny 阳光:改变变量名有什么用?我不懂诶。 :-\
  • @Santiago Hernández 是对的。

标签: android android-recyclerview


【解决方案1】:

您不是在更新适配器类中的 myNotesList,而是在活动类中。但是适配器使用它的本地 myNotesList。

点击按钮,用可用的最新数据更新适配器的 myNotesList 并通知适配器。

编辑
将最新数据传递给适配器。在适配器类中有这个方法并在 notifyDataSetChanged() 之前调用它;

public void updateNotes(ArrayList<String> notesList) {
    myNotesList = notesList; 
}

【讨论】:

  • 我怎样才能再次更新它,我需要在插入每个元素时一次又一次地初始化吗?或者有什么办法可以更新。 ?
  • 您只需将最新数据传递给适配器。在适配器类中有这个方法并在 notifyDataSetChanged() 之前调用它; public void updateNotes(ArrayList notesList) { myNotesList = notesList; }
  • 我试一试,告诉你结果如何。
  • 好。在确保它对您有帮助之前,您无需投票赞成任何答案。这可能会导致其他寻求者的困惑。 :) 你可以接受答案。
  • 他们试图为我提供答案,我很感激,这很有意义。实际上他们指定的内容是正确的(通常也不是我的回答)这就是我投票的原因。无论如何...非常感谢您的回答。我因这个错误坐了 2 天。大声笑...你解决了它。再次感谢
【解决方案2】:

1.您在将适配器设置为 listview 后正在初始化您的 dbhelper,因此它最初不能包含任何数据

2.更新recycler view数据列表如下

myNotesList.clear();
myNotesList.addAll(dbHelper.databasetostring());
adapter3.notifyDataSetChanged();

【讨论】:

  • 1.我需要先初始化吗? 2. 如果我这样做,每当我向列表视图添加项目时,我都需要重新加载所有数据。
  • 将一项添加到列表视图比重新加载所有项以插入单个项更好?如果我错了,请纠正我。
  • 你是对的。使用 adapter3.notifyItemInserted(position);用于更新特定项目。
【解决方案3】:

您的 SimpleRecyclerViewAdapter 有问题,只需更改:

while (i < myNotesList.size()) {
    myNotesList.add(myList.get(i).toString());
}

为此:

myNotesList = myList;

在你的活动printData()更改:

myNotesList=dbHelper.databasetostring();

为此:

myNotesList.clear();
myNotesList.addAll(dbHelper.databasetostring());
adapter3.notifyDataSetChanged();

说明:

首先你初始化myNotesList变量:

myNotesList = new ArrayList<>();

然后你初始化adapter3

adapter3 = new SimpleRecycler3Adapter(myNotesList);

但是您的适配器没有保存引用,而是将其数据复制到另一个变量中:

while (i < myNotesList.size()) {
    myNotesList.add(myList.get(i).toString());
}

这样做,如果您更改 activity 中的 myNotesList 变量,则不会修改适配器的数据集。

在您的方法printData() 中,您更改了myNotesList 变量。这不会触及您的适配器或其数据

public void printData(){
    Log.d("DB","Constructor");
    myNotesList=dbHelper.databasetostring();
    Log.d("DB","Data came"+myNotesList.get(myNotesList.size()-1));
    //  adapter3 = new SimpleRecycler3Adapter(myNotesList);
    // rv.setAdapter(adapter3);
    adapter3.notifyDataSetChanged();
}

【讨论】:

  • 那么我应该在我的代码中做些什么来更新我的列表?
  • 嗨 Ganesh,只需输入 myNotesList = myList; 而不是您的 while。这是在你的 SimpleRecycler3Adapter 的构造函数中,就是这样
  • 在初始化时只调用了适配器的构造函数。在那之后,即使是一次它也被调用,onBind onCreateViewHolder 也没有被调用
  • 我认为这是因为dbHelper.databasetostring(); 也在返回一个新的ArrayList 实例
  • 每次用户点击按钮时都初始化适配器不是一个好习惯,这就是为什么它被称为Recycler
【解决方案4】:

您不能通过更改 myList 来更改 myNotesList。

   public SimpleRecycler3Adapter(ArrayList<String> myList) {
        Log.d(TAG,"Constructor");

            Log.d(TAG,"Not null");
          //  int i = 0;
           // while (i < myNotesList.size()) {
          //      myNotesList.add(myList.get(i).toString());
          //  }
            this.myNotesList = myList;
            Log.d(TAG,"finish");
    }

【讨论】:

  • 谢谢你的回答,我试试看再说。
【解决方案5】:

当您确切知道数据收集发生了什么变化时,致电notifyDataSetChanged() 不是一个好主意。 请参阅此实现here。 他们甚至记录了在此doc 中使用notifyDataSetChanged() 作为最后手段。

如果您使用notifyItemInserted() 等方法,您将免费获得漂亮的动画。

也不要继续完全替换集合对象,请参阅附加的实现链接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    相关资源
    最近更新 更多