如何解决在notifyDataSetChanged 上未调用GetView,ListView 卡住
我遇到了一个问题,我在联系人应用程序中创建了带有自定义筛选的自定义适配器,它可以很好地筛选联系人姓名,并且已正确保存已过滤的联系人列表。问题是,当我在 searchView 中输入任何内容时,找到的行数是正确的,但有关找到的行的信息不正确。问题似乎与适配器中的 getView 函数有关,它在应该调用时没有调用。例如,如果我有三个联系人:“abc”、“aaa”、“aba”,并且它们按从上到下的顺序显示在开始处,那么如果我在 searchView 中键入“ab”,则它会找到 2 行,但它们仍然与开始时相同,它们应该是“abc”和“aba”,但它们是“abc”和“aaa”。适配器创建的第一个视图似乎由于某种原因卡住了。
我的活动课:
package com.example.androidlab;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import java.lang.reflect.Type;
import java.util.ArrayList;
public class AllContactsActivity extends AppCompatActivity {
static ArrayList<Contact> contacts = new ArrayList<>();
ContactsAdapter contactsAdapter;
ListView listView;
SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_contacts);
FloatingActionButton addContact = findViewById(R.id.newContact);
listView = findViewById(R.id.allContactsList);
searchView = findViewById(R.id.searchContacts);
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("com.tanay.thunderbird.contacts",Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString("contacts",null);
Type type = new TypeToken<ArrayList<Contact>>() {
}.getType();
contacts = gson.fromJson(json,type);
if (contacts == null) {
contacts = new ArrayList<>();
}
if (contacts.size() == 0)
Toast.makeText(this,"There are no contacts.",Toast.LENGTH_LONG).show();
contactsAdapter = new ContactsAdapter(this,contacts);
listView.setAdapter(contactsAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
Intent intent = new Intent(getApplicationContext(),EditContactActivity.class);
intent.putExtra("noteID",position);
startActivity(intent);
finish();
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
contactsAdapter.getFilter().filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String query) {
contactsAdapter.getFilter().filter(query);
return false;
}
});
addContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),NewContactActivity.class);
startActivity(intent);
finish();
}
});
}
@Override
public void onBackPressed() {
finish();
}
}
我的适配器类:
package com.example.androidlab;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
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.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class ContactsAdapter extends BaseAdapter implements Filterable {
Context context;
List<Contact> contacts;
List<Contact> filteredContacts;
ContactFilter mFilter = new ContactFilter();
String filterString;
ContactsAdapter(Context context,List<Contact> contacts) {
this.context = context;
this.contacts = contacts;
filteredContacts = contacts;
}
@Override
public int getCount() {
if(contacts.size() != filteredContacts.size() || filterString != null)
{
return filteredContacts.size();
}
else {
filteredContacts = contacts;
return contacts.size();
}
}
@Override
public Object getItem(int position) {
return contacts.get(position);
}
@Override
public long getItemId(int position) {
return contacts.indexOf(getItem(position));
}
@Override
public Filter getFilter() {
return mFilter;
}
private class ViewHolder {
ImageView imageView;
TextView name;
TextView phoneNumber;
}
@Override
public View getView(int position,View convertView,ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(AllContactsActivity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_contacts,null);
holder = new ViewHolder();
holder.name = (TextView) convertView.findViewById(R.id.contactName);
holder.imageView = (ImageView) convertView.findViewById(R.id.imageOfContact);
holder.phoneNumber = (TextView) convertView.findViewById(R.id.phoneNumber);
Contact contact;
if(filteredContacts.size() != contacts.size()) contact = filteredContacts.get(position);
else contact = contacts.get(position);
if (contact.getAvatar() == null) {
if (contact.getGender() == true)
holder.imageView.setImageResource(R.drawable.ic_man);
else holder.imageView.setImageResource(R.drawable.ic_woman);
} else {
byte[] decodedString = Base64.decode(contact.getAvatar(),Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString,decodedString.length);
holder.imageView.setImageBitmap(decodedByte);
}
holder.name.setText(contact.getName());
holder.phoneNumber.setText(String.valueOf(contact.getPhoneNumber()));
}
return convertView;
}
private class ContactFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<Contact> list = contacts;
int count = list.size();
final ArrayList<Contact> nList = new ArrayList<Contact>();
for (int i = 0; i < count; i++) {
if(contacts.get(i).getName().contains(filterString)) nList.add(contacts.get(i));
}
results.values = nList;
results.count = nList.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,FilterResults results) {
filteredContacts = (ArrayList<Contact>) results.values;
notifyDataSetChanged();
}
}
}
编辑:我在 getView 函数中去掉了 if(contentView == null) 并且一切正常
解决方法
对 convertView == null
的检查应该只处理 View
的膨胀和新 ViewHolder
的创建,其余的 getView
代码应该始终运行。>
public View getView(int position,View convertView,ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_contacts,null);
// attach a new holder to the inflated view
holder = new ViewHolder();
convertView.setTag(holder);
} else {
// get an existing holder from the existing view
holder = (ViewHolder) convertView.getTag();
}
// update your holder here:
// e.g. holder.name.setText(contact.getName());
return convertView;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。