0

我的listView似乎加载正确,但在测试时我认为它有问题。

我正在看这个教程:http ://android.amberfog.com/?p=296#more-296

我已经添加了这一行:

System.out.println("getView " + position + " " + convertView);

按照教程,logcat我应该在convertView向下滚动时看到值listView,例如:

System.out(947): getView 20 android.widget.LinearLayout@437430f8

但在我的logcat一切convertViews都是null。我什至不滚动listView,我的 122 行立即膨胀 - 判断logcat。所有值的形式为:

System.out: getView number is :21convertView is : null

难道我做错了什么?

这是我的代码:

public class SelectPhoneContactAdapter extends BaseAdapter {

    //define a list made out of SelectPhoneContacts and call it theContactsList
    public List<SelectPhoneContact> theContactsList;
    //define an array list made out of SelectContacts and call it arraylist
    private ArrayList<SelectPhoneContact> arraylist;
    Context _c;

    //define a ViewHolder to hold our name and number info, instead of constantly querying
    // findviewbyid. Makes the ListView run smoother
    // ViewHolder viewHolder;

    public SelectPhoneContactAdapter(final List<SelectPhoneContact> selectPhoneContacts, Context context) {
        theContactsList = selectPhoneContacts;
        _c = context;
        this.arraylist = new ArrayList<SelectPhoneContact>();
        this.arraylist.addAll(theContactsList);

    }


    @Override
    public int getCount() {
        System.out.println("the amount in arraylist :" + theContactsList.size());
        return arraylist.size();
    }

    @Override
    public Object getItem(int i) {
        return theContactsList.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)

    static class ViewHolder {
        //        In each cell in the listview show the items you want to have
//        Having a ViewHolder caches our ids, instead of having to call and load each one again and again
        TextView title, phone;
        CheckBox check;
    }

    @Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
        System.out.println("getView number is :" + i + "convertView is : " + convertView);

        ViewHolder viewHolder = null;

        if (convertView == null) {

            //if there is nothing there (if it's null) inflate the view with the layout
            LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = li.inflate(R.layout.phone_inflate_listview, null);

            viewHolder = new ViewHolder();

            //      So, for example, title is cast to the name id, in phone_inflate_listview,
//        phone is cast to the id called no etc
            viewHolder.title = (TextView) convertView.findViewById(R.id.name);
            viewHolder.phone = (TextView) convertView.findViewById(R.id.no);

            viewHolder.check = (CheckBox) convertView.findViewById(R.id.checkBoxContact);
            viewHolder.check.setVisibility(View.GONE);

            //remember the state of the checkbox
            viewHolder.check.setOnCheckedChangeListener((NewContact) _c);

            convertView.setTag(viewHolder);

        } else {

            viewHolder = (ViewHolder) convertView.getTag();

        }
//        store the holder with the view
            final SelectPhoneContact data = (SelectPhoneContact) theContactsList.get(i);
            //in the listview for contacts, set the name
            viewHolder.title.setText(data.getName());
            //in the listview for contacts, set the number
            viewHolder.phone.setText(data.getPhone());

            viewHolder.check.setChecked(data.isSelected());
            viewHolder.check.setTag(data);

        return convertView;

    }
}

在我的活动中,我使用一个函数来测量列表视图在屏幕上加载之前的高度,这可能是问题的一部分。不确定是否可以解决,但如果可以,那就太好了。

从我的 NewContact.java:

 @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            adapter = new SelectPhoneContactAdapter(selectPhoneContacts, NewContact.this);

            adapter.notifyDataSetChanged();
            listView.setAdapter(adapter);

            justifyListViewHeightBasedOnChildren(listView);

        }

justifyListViewHeightBasedOnChildren 函数:

//this is the function we call to measure the height of the listview
//we need this because there are problems with a listview within a scrollview
public static void justifyListViewHeightBasedOnChildren (ListView listView) {

    ListAdapter adapter = listView.getAdapter();

    if (adapter == null) {
        return;
    }
    ViewGroup vg = listView;
    int totalHeight = 0;
    for (int i = 0; i < adapter.getCount(); i++) {
        View listItem = adapter.getView(i, null, vg);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams par = listView.getLayoutParams();
    par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
    listView.setLayoutParams(par);
    listView.requestLayout();

    System.out.println("the getcount is " + adapter.getCount());
    System.out.println("the height is " + par.height);
}
4

1 回答 1

1

ListView调用getView()方法时,参数convertView是否具有非空值取决于是否ListView尝试“回收”视图。当先前在屏幕上的视图滚动到屏幕外(足够远)ListView以确保一段时间内不需要它并且可以重新使用(“回收”)以显示“新”视图即将在屏幕上滚动。

这里的想法是所有的孩子ListView都具有相同的结构;他们在View相同的地方有相同的 s。只是这些视图的内容发生了变化。因此,与其夸大另一种观点,不如回收不再使用的旧观点。

不管它是如何发生的,如果你ListView的空间足够大,可以同时容纳所有的孩子,那么回收是不可能的。你基本上创造了一个荣耀的LinearLayout. 这是否是一个问题真的取决于你和你的要求。但是当这种情况发生时,(视图回收)的整个“点”ListView就不会发生。

所有这一切就是说:查看所有 122 个调用中null的所有 122 个值意味着您使用的方式与预期不同。如果您的应用程序仍然可以完美运行,则无需更改它。但要知道,您没有在 Google 框架的预期边界内工作。convertViewgetView()ListView

于 2017-09-16T19:32:31.253 回答