如何在Android中使用BaseAdapter刷新自定义ListView

11

先生,我该如何使用BaseAdapter刷新我的自定义ListView。 我不知道在代码中放置什么或放置在哪里。 请帮帮我。 提前感谢。

public class EditDetails extends Activity{
public String nameChanged;
public String numChanged;
public String name;
public String num;
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.editdetails);
    final EditText sqlName = (EditText)findViewById(R.id.editName);
    final EditText sqlNumber = (EditText)findViewById(R.id.editNumber);
    name = CustomListView.name;
    num = CustomListView.number;
    Button bUpdate = (Button)findViewById(R.id.editUpdate);
    Button bView = (Button)findViewById(R.id.editView);
    sqlName.setText(name);
    sqlNumber.setText(num);

    bUpdate.setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {
            nameChanged = sqlName.getText().toString();
            numChanged = sqlNumber.getText().toString();
            GroupDb info = new GroupDb(EditDetails.this);
            info.open();
            long rowid = info.getRowId(name, num);
            info.updateNameNumber(rowid, nameChanged, numChanged);
            ArrayList<Contact> searchResults = info.getView();
            MyCustomBaseAdapter mcba = new MyCustomBaseAdapter(EditDetails.this, searchResults);
            Toast.makeText(getApplicationContext(), "Update Successful!", Toast.LENGTH_LONG).show();
            info.close();
            }
        });
    bView.setOnClickListener(new OnClickListener() {

        public void onClick(View arg0) {
            Intent intent = new Intent();
            intent.setClass(EditDetails.this, CustomListView.class);

            startActivityForResult(intent, 0);
            }
        });
}

}

这里是我显示列表视图的地方

public class CustomListView extends Activity {
final Context context = this;
public static String name;
public static String number;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    GroupDb info = new GroupDb(this);
    info.open();
    ArrayList<Contact> searchResults = info.getView();


    final ListView lv = (ListView) findViewById(R.id.srListView);
    lv.setAdapter(new MyCustomBaseAdapter(this, searchResults));
    info.close();

    lv.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> a, View v, int position, long id) {
            // TODO Auto-generated method stub
            Object o = lv.getItemAtPosition(position);
            final Contact fullObject = (Contact)o;
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
            alertDialogBuilder
            .setMessage("Select action")
            .setCancelable(false)
            .setPositiveButton("Edit", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,int id) {
                    Toast.makeText(getApplicationContext(), "Edit ", Toast.LENGTH_LONG).show();
                    name = fullObject.getName();
                    number = fullObject.getPhoneNumber();
                    Intent contactIntent = new Intent("myfolder.proj.EDITDETAILS");
                    startActivity(contactIntent);
                }
              })

以下是我的BaseAdapter类:

public class MyCustomBaseAdapter extends BaseAdapter {
private static ArrayList<Contact> searchArrayList;

private LayoutInflater mInflater;

public MyCustomBaseAdapter(Context context, ArrayList<Contact> results) {
    searchArrayList = results;
    mInflater = LayoutInflater.from(context);
}

public int getCount() {
    return searchArrayList.size();
}

public Object getItem(int position) {
    return searchArrayList.get(position);
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.custom_row_view, null);
        holder = new ViewHolder();
        holder.txtName = (TextView) convertView.findViewById(R.id.name);

        holder.txtPhone = (TextView) convertView.findViewById(R.id.phone);

        holder.status = (TextView) convertView.findViewById(R.id.status);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.txtName.setText(searchArrayList.get(position).getName());

    holder.txtPhone.setText(searchArrayList.get(position).getPhoneNumber());

    holder.status.setText(searchArrayList.get(position).getStatus());

    return convertView;
}

static class ViewHolder {
    TextView txtName;
    TextView txtPhone;
    TextView status;
}
}

2
为什么不调用适配器的 notifyDataSetChanged() 方法来更新 ListView 中的数据? - Abhijit
我应该把它放在哪里?我尝试将它放在我的EditDetails类中,像是mcba.notifyDataSetChanged(),但什么都没有发生。我不知道我是否做对了,但我觉得我没有。 - Usui Takumi
1
我认为是因为你需要在“CustomListView”活动中使用它,因为ListView是在该活动中定义的。“EditDetails”无法访问ListView或其适配器。 - Abhijit
我已经在我的自定义列表视图中使用了它,mcba.updateResults(searchResults); 最后的ListView lv =(ListView)findViewById(R.id.srListView); 但是,仍然得到相同的结果。 - Usui Takumi
5个回答

33
两种选择:要么保留传递到构造函数中的ArrayList的引用,以便稍后可以修改实际列表数据(因为未复制列表,因此在Adapter之外修改数据仍会更新Adapter引用的指针),或者重写Adapter以允许将列表重置为另一个对象。
在任一情况下,在ArrayList更改后,必须调用notifyDataSetChanged()以使用更改更新ListView。这可以在Adapter内部或外部完成。例如:
public class MyCustomBaseAdapter extends BaseAdapter {
    //TIP: Don't make this static, that's just a bad idea
    private ArrayList<Contact> searchArrayList;

    private LayoutInflater mInflater;

    public MyCustomBaseAdapter(Context context, ArrayList<Contact> initialResults) {
        searchArrayList = initialResults;
        mInflater = LayoutInflater.from(context);
    }

    public void updateResults(ArrayList<Contact> results) {
        searchArrayList = results;
        //Triggers the list update
        notifyDataSetChanged();
    }

    /* ...The rest of your code that I failed to copy over... */
}

HTH


那就是我如何使用notifyDataSetChanged(),谢谢。但是它仍然没有刷新我的列表,我想这可能是我的问题所在。 - Usui Takumi
哦,我明白了。看起来SQLite的rowid从0开始,而ListView从1开始,所以它不会改变。现在它正常工作了。顺便说一下,谢谢。 - Usui Takumi
1
@UsuiTakumi:我没看懂你上次的评论,是哪一项更改让它对你有效了???目前还不起作用。 - uniruddh

9

在BaseAdapter中创建一个自定义方法

例如:

 public void updateAdapter(ArrayList<Contact> arrylst) {
        this.arrylst= arrylst;

        //and call notifyDataSetChanged
        notifyDataSetChanged();
    }

在你想要调用的地方使用以下函数调用:例如

adapterObject.updateAdapter(在这里传递ArrayList);

完成。


3
只需使用BaseAdapter,无需使用上下文。
listsOfNotes.remove(listsOfNotes.get(position));
notifyDataSetChanged();

只需将此代码放在 setOnClickListner 上即可。


这对我有用,虽然不喜欢但给了我灵感!由于我使用Kotlin,所以我使用了list.removeAt()。我不记得Java中是否有removeAt - Armando Marques da S Sobrinho

2

感谢以上解决方案,对我非常有用。我在每个事件中调用listupdate方法。

  public void updateResults(List<TalebeDataUser> results) {
    talebeList = results;
    //Triggers the list update
    notifyDataSetChanged();
}

在更新列表后,我会刷新每个触摸中的按钮操作。例如,在我的listview项中有很多按钮要点击,因此每次触摸都会改变其他按钮的样式。

    private void setColor(TalebeDataUser talebeDataUser) {
    if (talebeDataUser.isVar()) {
        holder.mVar.setBackgroundResource(R.drawable.aw_secili);
        holder.mGorevli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mYok.setBackgroundResource(R.drawable.aw_shadow);
        holder.mIzinli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mHatimde.setBackgroundResource(R.drawable.aw_shadow);
    } else if (talebeDataUser.isGorevli()) {
        holder.mVar.setBackgroundResource(R.drawable.aw_shadow);
        holder.mGorevli.setBackgroundResource(R.drawable.aw_secili);
        holder.mYok.setBackgroundResource(R.drawable.aw_shadow);
        holder.mIzinli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mHatimde.setBackgroundResource(R.drawable.aw_shadow);
    } else if (talebeDataUser.isYok()) {
        holder.mVar.setBackgroundResource(R.drawable.aw_shadow);
        holder.mGorevli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mYok.setBackgroundResource(R.drawable.aw_secili);
        holder.mIzinli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mHatimde.setBackgroundResource(R.drawable.aw_shadow);
    } else if (talebeDataUser.isIzinli()) {
        holder.mVar.setBackgroundResource(R.drawable.aw_shadow);
        holder.mGorevli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mYok.setBackgroundResource(R.drawable.aw_shadow);
        holder.mIzinli.setBackgroundResource(R.drawable.aw_secili);
        holder.mHatimde.setBackgroundResource(R.drawable.aw_shadow);
    } else if (talebeDataUser.isHatimde()) {
        holder.mVar.setBackgroundResource(R.drawable.aw_shadow);
        holder.mGorevli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mYok.setBackgroundResource(R.drawable.aw_shadow);
        holder.mIzinli.setBackgroundResource(R.drawable.aw_shadow);
        holder.mHatimde.setBackgroundResource(R.drawable.aw_secili);
    }

}

这只是我其中一个按钮里面的一个例子

  holder.mYok.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //talebeList.remove(currentTalebe);
            setOgrenciNameByDurum(talebeList.get(i));
            talebeList.get(i).setYok(true);
            //setOgrenciNameByDurum(currentTalebe);
            talebeList.get(i).setVar(false);
            talebeList.get(i).setGorevli(false);
            talebeList.get(i).setIzinli(false);
            talebeList.get(i).setHatimde(false);
            updateResults(talebeList);
            setColor(talebeList.get(i));
            //saveCurrentTalebeOnShare(currentTalebe);
        }
    });

talebeList仅仅是一个List<MyModel> talebeList的列表


1
我将添加以下功能到我的自定义适配器来解决这个问题。
public void newCursor(Cursor cursor)
 {
  this.cursor=cursor;
  this.notifyDataSetChanged();
 }

从我的主类中,我通过重新查询数据库创建一个新的游标,然后通过这个函数将其发送到我的自定义适配器。

祝你好运


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接