Nullpointer exception when trying to access to ListView 's children

不想你离开。 提交于 2019-12-12 04:49:19

问题


I've created a Listfragment, which displays a List of views . Here is the 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);
}
}

Each row of the ListView displays an image and a text . It's the same image/text for the moment but I will put differents image/text later . The xml file of a row is 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>

This works fine . But, I wanted then in the ListFragment to modify the images of each row of the ListView . So I did it in the function onActivityCreated . And I got a NullPointerException when I am calling getChildAt( int ) . Why ? I mean, I'm calling the ListView AFTER onCreateView, and then I just want to : take a child view of this ListView, taking the imageview of this child, modifiying the imageview .

How can I access to the child views ?...

     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);

        }

    }

If you need some more code (like the activity wich is displaying the fragment, or other stuff), or informations, say it to me :)


回答1:


If you're seeking to modify the data that is presented, you must modify the data that backs the list, not the list itself.

There are three components: your data, your adapter which transforms your data into views that the list view can use, and the list view itself which requests views from the adapter based on list position.

If you need to change what's presented, change the data. Update the adapter with the new, changed, dataset, and call adapter.notifyDatasetChanged(). This will trigger your list view to request data from the adapter again, as its stale.

From where you are in your code now, you can do one of two things.

  • Instead of using a SimpleAdapter directly, create a class that extends BaseAdapter and use that. Add a method to change your data (setImages(List images) for example) which also includes the super call to notifyDatasetChanged() as the last statement.
  • create a new instance of SimpleAdapter with your new data and setListAdapter() again with the new adapter instance.

The first is preferred, but the tl:Dr; is "don't modify your views directly; it's an AdapterView because it's backed by a data source already."




回答2:


You are getting a NullPointerException because not all the cells are visible, so you will get a null view for those.



来源:https://stackoverflow.com/questions/27346938/nullpointer-exception-when-trying-to-access-to-listview-s-children

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!