尝试访问ListView的孩子时出现Nullpointer异常

时间:2014-12-07 19:38:08

标签: android android-listview android-listfragment

我创建了一个Listfragment,它显示了一个视图列表。 这是ListFragment:

public class AroundYou extends ListFragment {
private int[] images = new int[] {
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin,
        R.drawable.pinguin
};

private String[] names = new String[] {
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu",
        "Pingu"         
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

    // Each row in the list stores country name, currency and flag
    List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();

    for(int i=0;i<10;i++){
        HashMap<String, String> hm = new HashMap<String,String>();
        hm.put("name", names[i]);
        hm.put("image",Integer.toString(images[i]));
        aList.add(hm);
    }

    // Keys used in Hashmap
    String[] from = { "name","image"};

    // Ids of views in listview_layout
    int[] to = { R.id.name,R.id.image};

    // Instantiating an adapter to store each items
    // R.layout.listview_layout defines the layout of each item
    SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), aList, R.layout.around_you_line_of_list, from, to);

    setListAdapter(adapter);

    return super.onCreateView(inflater, container, savedInstanceState);
}
}

ListView的每一行都显示图像和文本。目前它是相同的图像/文本但我稍后会放置不同的图像/文本。 行的xml文件是around_you_line_of_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

<ImageView
    android:id="@+id/image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="2"
    android:contentDescription="@string/hello_world"
    android:paddingBottom="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp" />

<TextView
    android:id="@+id/name"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1" />

</LinearLayout>

这很好用。但是,我想在ListFragment中修改ListView的每一行的图像。所以我在onActivityCreated函数中做到了。当我调用getChildAt(int)时,我得到了一个N​​ullPointerException。为什么? 我的意思是,我正在调用ListView AFTER onCreateView,然后我只想:看一个这个ListView的子视图,拍摄这个孩子的imageview,修改imageview。

如何访问子视图?...

     public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
        ListView listView = getListView();
        for(int i = 0;i < 10;i++){
//I'm getting a null pointer exception at this line .
            View view = listView.getChildAt(i);
            ImageView imageview = (ImageView) view.findViewById(R.id.image);

            BitmapDrawable drawable = (BitmapDrawable)imageview.getDrawable();

//here I 'm getting a bitmap from the drawable, and then applying a function that modify
//the bitmap .
            Bitmap foreign_image = drawable.getBitmap();
            Canvas canvas = null;
            Bitmap bitmap = setBitmapClippedCircle(foreign_image,200,200,canvas);
//here I'm putting the result in the imageview .
            imageview.setImageBitmap(bitmap);

        }

    }

如果您需要更多代码(例如显示片段或其他内容的活动)或信息,请告诉我:)

2 个答案:

答案 0 :(得分:0)

你得到NullPointerException,因为并非所有单元格都可见,所以你会得到一个空视图。

答案 1 :(得分:0)

如果您要修改显示的数据,则必须修改支持列表的数据,而不是列表本身。

有三个组件:您的数据,将数据转换为列表视图可以使用的视图的适配器,以及根据列表位置从适配器请求视图的列表视图本身。

如果您需要更改显示的内容,请更改数据。使用新的,已更改的数据集更新适配器,然后调用adapter.notifyDatasetChanged()。这将触发您的列表视图,以再次从适配器请求数据,作为其陈旧。

现在,您可以在代码中的哪个位置执行以下操作之一。

  • 不是直接使用SimpleAdapter,而是创建一个扩展BaseAdapter并使用它的类。添加一种方法来更改您的数据(例如setImages(List images)),其中还包括对notifyDatasetChanged()的超级调用作为最后一个语句。
  • 使用新数据创建SimpleAdapter的新实例,并使用新适配器实例再次创建setListAdapter()

第一个是首选,但是tl:Dr;是“不要直接修改你的视图;它是一个AdapterView,因为它已经由数据源支持。”