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

Posted

技术标签:

【中文标题】尝试访问 ListView 的子项时出现 Nullpointer 异常【英文标题】:Nullpointer exception when trying to access to ListView 's children 【发布时间】:2015-02-05 10:56:32 【问题描述】:

我创建了一个 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_
    android:layout_
    android:orientation="horizontal" >

<ImageView
    android:id="@+id/image"
    android:layout_
    android:layout_
    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_
    android:layout_
    android:layout_weight="1" />

</LinearLayout>

这很好用。但是,我想在 ListFragment 中修改 ListView 每一行的图像。所以我在函数 onActivityCreated 中做到了。当我调用 getChildAt(int) 时,我得到了 NullPointerException。为什么 ? 我的意思是,我在 onCreateView 之后调用 ListView,然后我只想:获取此 ListView 的子视图,获取此子视图的图像视图,修改图像视图。

如何访问子视图?...

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

        

    

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

【问题讨论】:

你见过有人这样的代码结构吗?因为据我记得(我可能错了),listview 不支持某些视图组功能..对吗?是的,让我看看 我不太明白你的评论。其实我是用这个教程来做的:wptrafficanalyzer.in/blog/… 但事实是,我想把图片放入列表后修改 【参考方案1】:

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

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

如果您需要更改显示的内容,请更改数据。使用新的、更改的数据集更新适配器,然后调用 adapter.notifyDatasetChanged()。这将触发您的列表视图再次从适配器请求数据,因为它已经过时了。

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

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

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

【讨论】:

谢谢。我正在尝试做第一个。但是我正在努力使用 View getView(int position, View convertView, ViewGroup parent) 方法,我看不到它是如何实现的。 @PtitSualty 我写了一个similar answer previously。在那里,我为getView(int, View, ViewGroup) 添加了存根实现,希望能解释每个参数的用途(来自我添加的辅助方法的名称)【参考方案2】:

您将获得NullPointerException,因为并非所有单元格都可见,因此您将获得这些单元格的空视图。

【讨论】:

如果我无法访问它们,我该如何修改它们?我想我必须让它们可见。具体来说,我该怎么做?因为当我运行应用程序 WHITHOUT onActivityCreated 时,我可以看到列表的行(但图像尚未修改)。所以我假设它们是可见的。 对不起,我没有看到你获得 NPE 的那一行,看起来你的 ListView 是空的 但是,如果我在不使用 onActivityCreated 时可以看到所有行(及其元素),它怎么可能为 null?我现在很困惑:/

以上是关于尝试访问 ListView 的子项时出现 Nullpointer 异常的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用导入的 js 函数启动 html 页面时出现“CORS 策略已阻止从源‘null’访问脚本”错误

Android ViewBinding 有时会在绑定对象处返回 null,因此在尝试访问视图时出现空指针异常

访问 webhook URL 时出现错误“操作错误:没有匹配的意图处理程序:null”

Flutter 在尝试使用 Dismissible ListView 删除 futurebuilder 中的项目时出现范围错误

调用 ListView.addHeaderView() 时出现 ClassCastException?

尝试从 Kotlin 中的另一个活动访问 EditText 时出现空指针异常