【问题标题】:Android ListView Issues in Android 2.XAndroid 2.X 中的 Android ListView 问题
【发布时间】:2012-12-23 19:22:42
【问题描述】:

我创建了一个自定义数组适配器来填充列表视图,当活动加载列表视图时文本消失。

PlacesListAdapter.java

public class PlacesListAdapter extends ArrayAdapter<Place> implements
        Filterable {
    public Context context;
    private List<Place> places, orig, itemDetailsrrayList;
    private PlaceFilter filter;

    public PlacesListAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
    }

    public PlacesListAdapter(Context context, int resource, List<Place> places) {
        super(context, resource, places);
        this.context = context;
        this.places = places;

        itemDetailsrrayList = places;
        orig = new ArrayList<Place>(itemDetailsrrayList);

        filter = new PlaceFilter();
        // imageLoader = new ImageLoader(context.getApplicationContext());

    }

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

    public Place getItem(int position) {
        return itemDetailsrrayList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;

        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item_place, null);
        }

        Place place = places.get(position);

        if (place != null) {

            TextView place_name = (TextView) view
                    .findViewById(R.id.place_title);
            TextView place_distance = (TextView) view
                    .findViewById(R.id.place_distance);
            ImageView place_category_icon = (ImageView) view
                    .findViewById(R.id.place_category_icon);

            if (place_name != null) {
                place_name.setText(place.getPlaceTitle());
            }

            if (place_distance != null) {
                place_distance.setText("198");
            }

            if (place_category_icon != null) {
                place_category_icon.setImageResource(R.drawable.icon_category);
            }

        }

        // Setting Alternative Row Colors
        if (position % 2 == 0) {
            view.setBackgroundResource(R.drawable.list_view_place_row_1);
        } else {
            view.setBackgroundResource(R.drawable.list_view_place_row_2);
        }

        return view;
    }

    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        return filter;
    }

    private class PlaceFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults oReturn = new FilterResults();
            ArrayList<Place> results = new ArrayList<Place>();
            if (orig == null)
                orig = itemDetailsrrayList;
            if (constraint != null) {
                if (orig != null && orig.size() > 0) {
                    for (Place g : orig) {
                        if (g.getPlaceTitle()
                                .toLowerCase()
                                .startsWith(constraint.toString().toLowerCase()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            itemDetailsrrayList = (ArrayList<Place>) results.values;
            notifyDataSetChanged();
        }

    }
}

Place.java

public class Place {
    Integer placeId;
    String placeName = "", placeDistance = "", placeCategoryIcon = "";

    public Place(int placeId, String placeName, String placeDistance,
            String placeCategoryIcon) {
        this.placeId = placeId;
        this.placeName = placeName;
        this.placeDistance = placeDistance;
        this.placeCategoryIcon = placeCategoryIcon;
    }

    public Integer getPlaceId() {
        return placeId;
    }

    public void setPlaceId(int placeId) {
        this.placeId = placeId;
    }

    public String getPlaceName() {
        return placeName;
    }

    public void setPlaceName(String placeName) {
        this.placeName = placeName;
    }

    public String getPlaceDistance() {
        return placeDistance;
    }

    public void setPlaceDistance(String placeDistance) {
        this.placeDistance = placeDistance;
    }

    public String getPlaceCategoryIcon() {
        return placeCategoryIcon;
    }

    public void setPlaceCategoryIcon(String placeCategoryIcon) {
        this.placeCategoryIcon = placeCategoryIcon;
    }

}

MainActivity

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        setContentView(R.layout.activity_main);

        context = this;

        Log.i("Nomad", "onCreate");

        List<Place> thePlaces = new ArrayList<Place>();
        for (int i = 0; i < places.length; i++) {
            Place pl = new Place(i, places[i], "NO_DISTANCE", "NO_CATEGORYICON");
            thePlaces.add(pl);
        }

        listView = (ListView) findViewById(R.id.place_list);
        listView.setEmptyView(findViewById(R.id.empty));

        adapter = new PlacesListAdapter(MainActivity.this, thePlaces);

        listView.setAdapter(adapter);

        listView.setTextFilterEnabled(true);

        mSearchView = (SearchView) findViewById(R.id.action_search);

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> a, View view, int position,
                    long id) {

                startActivity(new Intent(MainActivity.this, PlaceActivity.class));
            }
        });
    }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@color/primary_white" >

    <ListView
        android:id="@+id/place_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:fadingEdge="none" >
    </ListView>

    <TextView
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="20dp"
        android:text="@string/list_view_place_empty"
        android:textColor="@color/black"
        android:textSize="18sp" />

</LinearLayout>

list_item_place.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingBottom="10dp"
    android:paddingTop="10dp" >

    <ImageView
        android:id="@+id/place_category_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:contentDescription="ss"
        android:paddingLeft="10dp"
        android:paddingRight="15dp"
        android:src="@drawable/icon_category" />

    <TextView
        android:id="@+id/place_distance"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:paddingRight="15dp"
        android:textColor="@color/black"
        android:text="320" />

    <TextView
        android:id="@+id/place_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@+id/place_category_icon"
        android:ellipsize="end"
        android:paddingRight="50dp"
        android:singleLine="true"
        android:text="Place Name"
        android:textColor="#191919"
        android:textSize="18sp" />

</RelativeLayout>

这是它在加载时的显示方式

在尝试滚动内容时重新出现。

【问题讨论】:

  • 我总是推荐使用这种方法来膨胀适配器视图:inflater.inflate(R.layout.list_item_place, parent, false);

标签: android android-listview actionbarsherlock android-arrayadapter custom-adapter


【解决方案1】:

你必须删除

getWindow().requestFeature(Window.FEATURE_ACTION_BAR);

Window.FEATURE_ACTION_BAR 已添加到 Honeycomb (3.0) 中,不适用于 Android 2.x 设备。 为了与旧版本保持兼容,您可以在 MainActivity.java 中使用这个 sn-p:

int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= 11) {
   getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
}

附加代码:(这些是您上面示例的派生类,由于缺少类,必须更改、注释或以某种方式操作才能编译某些元素)

MainActivity.java

在 MainActivity 中,我所做的唯一真正更改是禁用小于 11 的 API 级别的操作栏。并且在插入位置后启动 notifyDatasetchanged()。

public class MainActivity extends Activity {

    protected static final String TAG = "MainActivity";

    private MainActivity context;

    private ListView listView;

    private PlacesListAdapter adapter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v(TAG, "onCreate()");
        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (currentapiVersion >= 11) {
            getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        }

        setContentView(R.layout.activity_main);

        context = this;

        Log.i("Nomad", "onCreate");

        List<Place> thePlaces = new ArrayList<Place>();
        String[] places = new String[10];
        places[0] = "hallo1";
        places[1] = "hallo2";
        places[2] = "hallo3";
        places[3] = "hallo4";
        places[4] = "hallo5";
        places[5] = "hallo6";
        places[6] = "hallo7";
        places[7] = "hallo8";
        places[8] = "hallo9";
        places[9] = "hallo10";

        for (int i = 0; i < places.length; i++) {
            Place pl = new Place(i, places[i], "NO_DISTANCE", "NO_CATEGORYICON");
            thePlaces.add(pl);
        }

        listView = (ListView) findViewById(R.id.place_list);
        listView.setEmptyView(findViewById(R.id.empty));

        adapter = new PlacesListAdapter(this, R.layout.list_item_place,
                thePlaces);

        listView.setTextFilterEnabled(true);

        // mSearchView = (SearchView) findViewById(R.id.action_search);

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> a, View view, int position,
                    long id) {

                startActivity(new Intent(MainActivity.this, MainActivity.class));
            }
        });
        listView.setAdapter(adapter);
        **adapter.notifyDataSetChanged();**
    }
}

PlacesListAdapter.java

对于适配器,我强烈建议使用 ViewHolder,它包含每个 List-Element-View 的 TextView 和 ImageView 引用。

public class PlacesListAdapter extends ArrayAdapter<Place> implements
        Filterable {
    private static final String TAG = "PlacesListAdapter";
    public Context context;
    private List<Place> places, orig, itemDetailsrrayList;
    private PlaceFilter filter;

    public PlacesListAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
    }

    public PlacesListAdapter(Context context, int resource, List<Place> places) {
        super(context, resource, places);
        this.context = context;
        this.places = places;

        itemDetailsrrayList = places;
        orig = new ArrayList<Place>(itemDetailsrrayList);

        filter = new PlaceFilter();
        // imageLoader = new ImageLoader(context.getApplicationContext());

    }

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

    public Place getItem(int position) {
        return itemDetailsrrayList.get(position);
    }

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

    /**
     * This is the holder that will provide fast access to arbitrary objects and
     * views. Use a subclass to adapt it for your needs.
     */
    public static class ViewHolder {
        private final TextView place_name;
        private final TextView place_distance;
        private final ImageView place_category_icon;

        public ViewHolder(TextView place_name, TextView place_distance,
                ImageView place_category_icon) {
            this.place_name = place_name;
            this.place_distance = place_distance;
            this.place_category_icon = place_category_icon;
        }
    }

    protected ViewHolder createHolder(View v) {
        TextView place_name = (TextView) v.findViewById(R.id.place_title);
        TextView place_distance = (TextView) v
                .findViewById(R.id.place_distance);
        ImageView place_category_icon = (ImageView) v
                .findViewById(R.id.place_category_icon);
        ViewHolder tvshowHolder = new ViewHolder(place_name, place_distance,
                place_category_icon);

        return tvshowHolder;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view = convertView;
        ViewHolder holder;
        if (view == null) {
            LayoutInflater inflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item_place, null);
            // Log.v(TAG, "generating new view");
            holder = createHolder(view);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        Place place = places.get(position);
        if (place != null) {
            // Log.v(TAG, place.getPlaceName());
            if (holder.place_name != null) {
                // Log.v(TAG, "setting placeName to " + place.getPlaceName());
                // place_name.setText(place.getPlaceTitle());
                holder.place_name.setText(place.getPlaceName());
            }

            if (holder.place_distance != null) {
                holder.place_distance.setText("198");
            }

            if (holder.place_category_icon != null) {
                holder.place_category_icon
                        .setImageResource(R.drawable.ic_launcher);
            }

        }

        // Setting Alternative Row Colors
        if (position % 2 == 0) {
            view.setBackgroundResource(R.drawable.ic_launcher);
        } else {
            view.setBackgroundResource(R.drawable.ic_launcher);
        }

        return view;
    }

    @Override
    public Filter getFilter() {
        // TODO Auto-generated method stub
        return filter;
    }

    private class PlaceFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults oReturn = new FilterResults();
            ArrayList<Place> results = new ArrayList<Place>();
            if (orig == null)
                orig = itemDetailsrrayList;
            if (constraint != null) {
                if (orig != null && orig.size() > 0) {
                    for (Place g : orig) {
                        if (g.getPlaceTitle()
                                .toLowerCase()
                                .startsWith(constraint.toString().toLowerCase()))
                            results.add(g);
                    }
                }
                oReturn.values = results;
            }
            return oReturn;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            itemDetailsrrayList = (ArrayList<Place>) results.values;
            notifyDataSetChanged();
        }

    }
}

【讨论】:

  • 这会影响列表视图吗?
  • 不,在我的本地测试中,一切都很好。如果您想要一些代码,请告诉我,我会在答案中附加更多内容。
  • 希望代码示例有所帮助,它在我测试它们的两种环境中都能正常工作(api lvl 8 和 16)如果您有任何问题,请不要犹豫:)
  • 天哪,我在 Android 2.3.4 设备上使用 ActionBar 时遇到了同样的问题。我看到的不是字母,而是白色矩形(而我的文本应该是白色的)。在为 API 版本放置此 if 语句后,问题就消失了,并且在 Activity 启动时正确显示了文本视图。谢啦。 +1
  • 过去 3 天一直在与 @uerceg 一样的问题苦苦挣扎,但我们的应用从不请求该功能,并通过扩展 SherlockFragmentActivity 来使用 ActionBarSherlock。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多