【发布时间】:2016-01-29 02:40:31
【问题描述】:
我正在使用自定义适配器来显示我的列表视图。首先,我使用 AsyncTask 检索要在列表视图中显示的信息,因为这些信息是从 PHP Web 服务中检索的。然后,要从列表视图中删除一个项目,它会再次调用 Web 服务来执行此操作。成功删除所选项目后,onPostExecute 方法会接收结果并删除该项目。但是,只有在刷新片段时,它才会从我的列表视图中删除。
@Override
public boolean onContextItemSelected(final MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case VIEW_CONTACT:
// other actions
return true;
case EDIT_CONTACT:
return true;
case DELETE_CONTACT:
// Create AlertDialog for confirmation
AlertDialog.Builder builder = new AlertDialog.Builder(context)
.setTitle("Delete Contact List")
.setMessage("Are you sure you want to delete this list?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// continue with delete
new DeleteTask().execute();
dialog.cancel();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setIcon(android.R.drawable.ic_dialog_alert);
builder.show();
return true;
}
return true;
}
上面的代码显示了上下文菜单,当用户选择删除时,一个警告对话框将提示他们确认操作。当他们选择 ok 时,它会执行 AsyncTask,如下所示:
public class DeleteTask extends AsyncTask<Void, String ,String>{
@Override
protected void onPreExecute(){
super.onPreExecute();
pDialog = ProgressDialog.show(context, null, "Loading", true);
}
@Override
protected String doInBackground(Void... params){
return DeleteData();
}
@Override
protected void onPostExecute(String result){
super.onPostExecute(result);
pDialog.dismiss();
if (result.equals("1")) {
mAdapter.notifyDataSetChanged(); // this bit didn't work in updating/refreshing the listview
Toast.makeText(context, "List successfully deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context,
"List not deleted", Toast.LENGTH_LONG).show();
}
}
private String DeleteData(){
int success = 0;
try {
List<NameValuePair> paramas = new ArrayList<NameValuePair>();
paramas.add(new BasicNameValuePair("listid", listID));
JSONParser jParserDelete = new JSONParser();
JSONObject jsonObjectA = jParserDelete.makeHttpRequest(Constant.URL
+ "removeList.php", "GET", paramas);
success = jsonObjectA.getInt(Constant.TAG_SUCCESS);
Log.d("contacts", jsonObjectA.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
return Integer.toString(success);
}
}
我尝试使用mAdapter.notifyDataSetChanged();,但没有成功。我知道 mAdapter 是 Activity 类中的全局变量。另外,要注意我的适配器是一个自定义类。我最初想全局声明一个布尔值deleteSuccess,然后在onPostExecute 将其设置为true,结果== 1,但onContextItemSelected 不等待onPostExecute,只是将deleteSuccess 的值设为`false。
底线是,如何从适配器中删除所选项目,从而在删除项目后立即成功“刷新”ListView?
编辑:
这是我的自定义适配器类
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.SectionIndexer;
import android.widget.TextView;
import java.util.ArrayList;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
public class ContactsAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer, Filterable {
private final Context mContext;
private int[] mSectionIndices;
private Character[] mSectionLetters;
private LayoutInflater mInflater;
private ArrayList<String> mArrayList;
// for search function
private ArrayList<Glossary> glossariesList;
private ArrayList<Glossary> glossariesListForSearch;
public ContactsAdapter(Context context, ArrayList<String> arrayList, ArrayList<Glossary> glossaries) {
super();
mContext = context;
mArrayList = arrayList;
mInflater = LayoutInflater.from(context);
mSectionIndices = getSectionIndices();
mSectionLetters = getSectionLetters();
this.glossariesList = glossaries;
glossariesListForSearch = glossaries;
}
private int[] getSectionIndices() {
ArrayList<Integer> sectionIndices = new ArrayList<>();
char lastFirstChar = mArrayList.get(0).charAt(0);
sectionIndices.add(0);
for (int i = 1; i < mArrayList.size(); i++) {
if (mArrayList.get(i).charAt(0) != lastFirstChar) {
lastFirstChar = mArrayList.get(i).charAt(0);
sectionIndices.add(i);
}
}
int[] sections = new int[sectionIndices.size()];
for (int i = 0; i < sectionIndices.size(); i++) {
sections[i] = sectionIndices.get(i);
}
return sections;
}
private Character[] getSectionLetters() {
Character[] letters = new Character[mSectionIndices.length];
for (int i = 0; i < mSectionIndices.length; i++) {
letters[i] = mArrayList.get(mSectionIndices[i]).charAt(0);
}
return letters;
}
@Override
public int getCount() {
return glossariesList.size();
}
@Override
public Object getItem(int position) {
return glossariesList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.index_list_item_layout, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Glossary glossary = glossariesList.get(position);
holder.text.setText(glossary.getName());
return convertView;
}
@Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = mInflater.inflate(R.layout.index_header, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
// set header text as first char in name
CharSequence headerChar = glossariesList.get(position).getName().subSequence(0,1);
holder.text.setText(headerChar);
return convertView;
}
@Override
public long getHeaderId(int position) {
// return the first character of the country as ID because this is what
// headers are based upon
return glossariesList.get(position).getName().subSequence(0, 1).charAt(0);
}
@Override
public int getPositionForSection(int section) {
if (mSectionIndices.length == 0) {
return 0;
}
if (section >= mSectionIndices.length) {
section = mSectionIndices.length - 1;
} else if (section < 0) {
section = 0;
}
return mSectionIndices[section];
}
@Override
public int getSectionForPosition(int position) {
for (int i = 0; i < mSectionIndices.length; i++) {
if (position < mSectionIndices[i]) {
return i - 1;
}
}
return mSectionIndices.length - 1;
}
@Override
public Object[] getSections() {
return mSectionLetters;
}
class HeaderViewHolder {
TextView text;
}
class ViewHolder {
TextView text;
}
@Override
public Filter getFilter() {
return myFilter;
}
Filter myFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Glossary> tempGlossaryList = new ArrayList<>();
if (constraint != null && glossariesListForSearch != null) {
int length = glossariesListForSearch.size();
int i = 0;
while (i < length) {
Glossary item = glossariesListForSearch.get(i);
if (item.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempGlossaryList.add(item);
}
i++;
}
filterResults.values = tempGlossaryList;
filterResults.count = tempGlossaryList.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
glossariesList = (ArrayList<Glossary>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
【问题讨论】:
-
不清楚你是如何定义
mAdapter的,但你应该在某个地方调用mAdapter.remove()。 -
我已经为我的自定义适配器添加了代码。调用 mAdapter 后我没有得到删除方法,所以我认为我必须自己实现它。但是我应该怎么做呢?
-
您可能想要使用 ArrayAdapter 而不是 BaseAdapter。如果要保留BaseAdapter,则需要自己实现
remove -
@cricket_007 嘿,帮了大忙!谢谢你:-)
标签: java android listview android-asynctask