Android ListView 适配器崩溃 issue/Duplicates
Android ListView Adapter Crash issue/Duplicates
我主要是想通过同一个 ListView 适配器显示多个视图。但是,适配器最终会生成多个重复项,有时还会因 NullPointer 而崩溃。我的猜测是我完全错误地实现了适配器。这是我的完整代码:
The item could either be a photo or a text.
适配器:
public class FeedAdapter extends BaseAdapter {
static private Activity activity;
private static LayoutInflater inflater = null;
ArrayList<ActivityTable> actList = new ArrayList<ActivityTable>();
Holder holder;
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
activity = a;
this.actList = actList;
}
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
if (act.getType().equals("text")) {
convertView = inflater.inflate(R.layout.feed_single_text, null);
holder = new Holder();
//More code that Set the caption to the holder
convertView.setTag(holder);
}
if (act.getType().equals("photo")) {
convertView = inflater.inflate(R.layout.feed_single_picture, parent, false);
holder = new Holder();
holder.media = (ImageView) convertView.findViewById(R.id.postphoto);
//More code that Set the photo to the holder
convertView.setTag(holder);
}
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
public static class Holder {
ImageView media;
TextView caption;
}
}
我是否以错误的方式在同一个适配器中膨胀多个视图?谁能指出错误?
xml 文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/ImgFeed"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txtCaption"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
尝试一下你使用的是 ImageView 而不是 TextView
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.feed_layout, null);
holder = new Holder();
holder.caption = (TextView) convertView.findViewById(R.id.txtCaption);
holder.media = (ImageView) convertView.findViewById(R.id.ImgFeed);
if (act.getType().equals("text")) {
holder.media.setVisibility(View.GONE)
}
else if (act.getType().equals("photo")) {
holder.caption.setVisibility(View.GONE)
}
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
每行有 2 个不同的布局,所以我认为您应该添加
@Override
public int getViewTypeCount() {
return 2;
}
到您的列表视图适配器
在您的代码中,尝试在您的适配器
的构造函数中初始化您的 LayoutInflater
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
...
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
而且您还应该优化您的 ListView 性能
Here is my experience
有这3个就好了
@Override
public int getCount() {
return actList().size();
}
@Override
public Object getItem(int position) {
return actList().get(position);
}
@Override
public long getItemId(int position) {
return position;
}
这是重要的部分,
首先你必须告诉适配器有多少类型,
然后你必须告诉适配器如何确定类型。
这里我告诉type View Type = 2
@Override
public int getViewTypeCount() {
return 2;
}
在这里我告诉适配器我如何将类型号放入数组中
我使用 setType = 0 ||设置类型 = 1
个人偏好:我喜欢使用 int 而不是 String
@Override
public int getItemViewType(int position) {
return act.get(position).getType();
}
然后在 getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
int listViewItemType = getItemViewType(position);
if (v == null) {
..whatevever you doing to make v not null
}
if (listViewItemType == 0) {
//Do something
}else if(listViewItemType == 1){
// Do something different
}
return v;
}
是的,您会得到重复的项目,因为 Convertview 正在重复使用。创建 convertview 后,如果您滚动,则使用该视图。
所以最好使用单一布局,同时使用图像和文本。基于类型隐藏任何一个。
我主要是想通过同一个 ListView 适配器显示多个视图。但是,适配器最终会生成多个重复项,有时还会因 NullPointer 而崩溃。我的猜测是我完全错误地实现了适配器。这是我的完整代码:
The item could either be a photo or a text.
适配器:
public class FeedAdapter extends BaseAdapter {
static private Activity activity;
private static LayoutInflater inflater = null;
ArrayList<ActivityTable> actList = new ArrayList<ActivityTable>();
Holder holder;
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
activity = a;
this.actList = actList;
}
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
if (act.getType().equals("text")) {
convertView = inflater.inflate(R.layout.feed_single_text, null);
holder = new Holder();
//More code that Set the caption to the holder
convertView.setTag(holder);
}
if (act.getType().equals("photo")) {
convertView = inflater.inflate(R.layout.feed_single_picture, parent, false);
holder = new Holder();
holder.media = (ImageView) convertView.findViewById(R.id.postphoto);
//More code that Set the photo to the holder
convertView.setTag(holder);
}
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
public static class Holder {
ImageView media;
TextView caption;
}
}
我是否以错误的方式在同一个适配器中膨胀多个视图?谁能指出错误?
xml 文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/ImgFeed"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txtCaption"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
尝试一下你使用的是 ImageView 而不是 TextView
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
final ActivityTable act = actList.get(position);
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.feed_layout, null);
holder = new Holder();
holder.caption = (TextView) convertView.findViewById(R.id.txtCaption);
holder.media = (ImageView) convertView.findViewById(R.id.ImgFeed);
if (act.getType().equals("text")) {
holder.media.setVisibility(View.GONE)
}
else if (act.getType().equals("photo")) {
holder.caption.setVisibility(View.GONE)
}
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
return convertView;
}
每行有 2 个不同的布局,所以我认为您应该添加
@Override
public int getViewTypeCount() {
return 2;
}
到您的列表视图适配器
在您的代码中,尝试在您的适配器
LayoutInflater
public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
...
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
而且您还应该优化您的 ListView 性能
Here is my experience
有这3个就好了
@Override
public int getCount() {
return actList().size();
}
@Override
public Object getItem(int position) {
return actList().get(position);
}
@Override
public long getItemId(int position) {
return position;
}
这是重要的部分, 首先你必须告诉适配器有多少类型, 然后你必须告诉适配器如何确定类型。
这里我告诉type View Type = 2
@Override
public int getViewTypeCount() {
return 2;
}
在这里我告诉适配器我如何将类型号放入数组中 我使用 setType = 0 ||设置类型 = 1 个人偏好:我喜欢使用 int 而不是 String
@Override
public int getItemViewType(int position) {
return act.get(position).getType();
}
然后在 getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
int listViewItemType = getItemViewType(position);
if (v == null) {
..whatevever you doing to make v not null
}
if (listViewItemType == 0) {
//Do something
}else if(listViewItemType == 1){
// Do something different
}
return v;
}
是的,您会得到重复的项目,因为 Convertview 正在重复使用。创建 convertview 后,如果您滚动,则使用该视图。
所以最好使用单一布局,同时使用图像和文本。基于类型隐藏任何一个。