在 recyclerview 中更改数据
change data in recyclerview
看来我还是搞不懂 notifydatasetchanged 是如何工作的。我试图更新适配器中的变量,但未能成功。我尝试如下所示,还尝试定义单独的 class 导航抽屉项目,但什么也做不了。
基本上,计数应该不时更新,所以我只需要在 NavDrawer 中更新它。我肯定对 notifydatasetchanged 的工作原理有一些误解。
我非常确定我过去使用 ListView 做了一些类似于方法 2 的事情。唯一的区别是,我在那种情况下使用了 ArrayList,但在这里我直接将数组存储在 NavDrawerList 中并将其传递给适配器。
方法一
public class ActivityMain extends AppCompatActivity{
private String[] navMenuTitles;
public int count;
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout mDrawerLayout;
ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
count = 20;
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new NavDrawerAdapter(navMenuTitles, count);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerLayout = (DrawerLayout) findViewById(R.id.DrawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.openDrawer, R.string.closeDrawer);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
public void updateCount(){
count = 10;
mAdapter.notifyDataSetChanged(); // DRAWER STILL SHOWS 20 EVEN IF I CALL THIS FUNCTION
}
}
public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.ViewHolder> {
private String[] mNavTitles;
private int count;
public NavDrawerAdapter(mNavTitles, mCount){
this.mNavTitles = mNavTitles;
this.count = mCount;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
TextView counter;
public ViewHolder (View itemView) {
textView = (TextView) itemView.findViewById(R.id.title);
counter = (TextView) itemView.findViewById(R.id.counter);
}
}
@Override
public NavDrawerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navdrawer_item,parent,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(NavDrawerAdapter.ViewHolder holder, int position) {
holder.textView.setText(mNavTitles[position]);
holder.counter.setText("" + _count);
}
@Override
public int getItemCount() {
return mNavTitles.length;
}
}
方法二
public class ActivityMain extends AppCompatActivity{
private String[] navMenuTitles;
private NavDrawerList navDrawerList;
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout mDrawerLayout;
ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new NavDrawerAdapter(new NavDrawerList(navMenuTitles, 20));
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerLayout = (DrawerLayout) findViewById(R.id.DrawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.openDrawer, R.string.closeDrawer);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
public void updateCount(){
navDrawerList.setNavCount(10);
mAdapter.notifyDataSetChanged(); // DRAWER STILL SHOWS 20 EVEN IF I CALL THIS FUNCTION
}
}
public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.ViewHolder> {
private String[] mNavTitles;
private int count;
public NavDrawerAdapter(mNavTitles, mCount){
this.mNavTitles = navDrawerList.getNavTitles();
this.count = navDrawerList.getNavCount();
}
}
public class NavDrawerList {
private String[] navTitles;
private int navCount;
public NavDrawerList(String[] navTitles, int navCount){
this.navTitles = navTitles;
this.navCount = navCount;
}
public String[] getNavTitles(){
return navTitles;
}
public int getNavCount(){
return navCount;
}
public void setNavCount(int navCount){
this.navCount = navCount;
}
}
如果您只更改列表 mNavTitles
,则不会更改适配器。
您需要在适配器内部更改它,就像您在构造函数中所做的那样:
public void updateList(String[] mNavTitles) {
this.mNavTitles = mNavTitles;
}
然后您调用 notifyDataSetChanged,如果有任何更改或添加,它将起作用,并将调用适当的 onBindViewHolder 或 onCreateViewHolder 方法。
我想如果我理解正确的话,你有一个字符串数组,有 20 个值。您正在传递一个计数(即要显示的项目数)以更新列表中的项目数,例如 10 或 20。问题是即使您更新计数,回收器视图方法 getItemCount()
正在返回 mNavTitles.length
即所有这些。因此,无论计数值如何,都会生成整个列表。所以一种解决方案是:
在你的方法 1
改变
@Override
public int getItemCount() {
return mNavTitles.length;
}
至
@Override
public int getItemCount() {
return count;
}
还要确保 count
的值永远不会大于 mNavTitles.length
因为如果是这样,您的代码将抛出 index out of bounds
错误..
看来我还是搞不懂 notifydatasetchanged 是如何工作的。我试图更新适配器中的变量,但未能成功。我尝试如下所示,还尝试定义单独的 class 导航抽屉项目,但什么也做不了。
基本上,计数应该不时更新,所以我只需要在 NavDrawer 中更新它。我肯定对 notifydatasetchanged 的工作原理有一些误解。
我非常确定我过去使用 ListView 做了一些类似于方法 2 的事情。唯一的区别是,我在那种情况下使用了 ArrayList,但在这里我直接将数组存储在 NavDrawerList 中并将其传递给适配器。
方法一
public class ActivityMain extends AppCompatActivity{
private String[] navMenuTitles;
public int count;
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout mDrawerLayout;
ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
count = 20;
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new NavDrawerAdapter(navMenuTitles, count);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerLayout = (DrawerLayout) findViewById(R.id.DrawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.openDrawer, R.string.closeDrawer);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
public void updateCount(){
count = 10;
mAdapter.notifyDataSetChanged(); // DRAWER STILL SHOWS 20 EVEN IF I CALL THIS FUNCTION
}
}
public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.ViewHolder> {
private String[] mNavTitles;
private int count;
public NavDrawerAdapter(mNavTitles, mCount){
this.mNavTitles = mNavTitles;
this.count = mCount;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
TextView counter;
public ViewHolder (View itemView) {
textView = (TextView) itemView.findViewById(R.id.title);
counter = (TextView) itemView.findViewById(R.id.counter);
}
}
@Override
public NavDrawerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.navdrawer_item,parent,false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(NavDrawerAdapter.ViewHolder holder, int position) {
holder.textView.setText(mNavTitles[position]);
holder.counter.setText("" + _count);
}
@Override
public int getItemCount() {
return mNavTitles.length;
}
}
方法二
public class ActivityMain extends AppCompatActivity{
private String[] navMenuTitles;
private NavDrawerList navDrawerList;
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
DrawerLayout mDrawerLayout;
ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
mRecyclerView.setHasFixedSize(true);
mAdapter = new NavDrawerAdapter(new NavDrawerList(navMenuTitles, 20));
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mDrawerLayout = (DrawerLayout) findViewById(R.id.DrawerLayout);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.openDrawer, R.string.closeDrawer);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
public void updateCount(){
navDrawerList.setNavCount(10);
mAdapter.notifyDataSetChanged(); // DRAWER STILL SHOWS 20 EVEN IF I CALL THIS FUNCTION
}
}
public class NavDrawerAdapter extends RecyclerView.Adapter<NavDrawerAdapter.ViewHolder> {
private String[] mNavTitles;
private int count;
public NavDrawerAdapter(mNavTitles, mCount){
this.mNavTitles = navDrawerList.getNavTitles();
this.count = navDrawerList.getNavCount();
}
}
public class NavDrawerList {
private String[] navTitles;
private int navCount;
public NavDrawerList(String[] navTitles, int navCount){
this.navTitles = navTitles;
this.navCount = navCount;
}
public String[] getNavTitles(){
return navTitles;
}
public int getNavCount(){
return navCount;
}
public void setNavCount(int navCount){
this.navCount = navCount;
}
}
如果您只更改列表 mNavTitles
,则不会更改适配器。
您需要在适配器内部更改它,就像您在构造函数中所做的那样:
public void updateList(String[] mNavTitles) {
this.mNavTitles = mNavTitles;
}
然后您调用 notifyDataSetChanged,如果有任何更改或添加,它将起作用,并将调用适当的 onBindViewHolder 或 onCreateViewHolder 方法。
我想如果我理解正确的话,你有一个字符串数组,有 20 个值。您正在传递一个计数(即要显示的项目数)以更新列表中的项目数,例如 10 或 20。问题是即使您更新计数,回收器视图方法 getItemCount()
正在返回 mNavTitles.length
即所有这些。因此,无论计数值如何,都会生成整个列表。所以一种解决方案是:
在你的方法 1
改变
@Override
public int getItemCount() {
return mNavTitles.length;
}
至
@Override
public int getItemCount() {
return count;
}
还要确保 count
的值永远不会大于 mNavTitles.length
因为如果是这样,您的代码将抛出 index out of bounds
错误..