Android Gridview和getChildAt与NullPointerException

时间:2011-11-07 23:33:39

标签: android gridview button nullpointerexception adapter

我有一个UI,它包含一个加载了自定义适配器的Gridview。一个ButtonAdapter,在这种情况下。因此网格加载正常,按钮点击功能就像我想要的那样,但现在我必须在按钮上指示它是“活动”选择。

我以为我会通过跟踪和改变背景来做到这一点。事实证明,并且基于SO上的几个帖子,当它们在屏幕外时,按钮实际上并不存在......甚至在滚动之后立即存在。在滚动后尝试更改按钮背景时,我经常会遇到NullPointerException。

我尝试将适配器中的视图更改为RadioButtons和ToggleButtons,但它们都提供了类似的限制。

问题似乎与我在网格上用来“取消选择”一个按钮的getChildAt()有关,或者其他什么,当选择另一个按钮时。

是否有针对此的解决方法,或者可能是其他类似功能的建议。可垂直滚动,网格状格式等......

感谢您的帮助。

编辑: 谢谢Craigy ......我忘记在那里放置一个平台o.0 ...我会添加android。

3 个答案:

答案 0 :(得分:1)

在适配器在getView()中创建的每个视图上设置一个标记。稍后通过gridView.findViewByTag()搜索带有该标记的视图,或者通过view.getTag()获取视图的标记。

答案 1 :(得分:1)

您是否考虑过使用Selector?由于忽略了buttonAdapter的工作原理或者你从中拉出的是什么,你可以设置任何View的背景可绘制,以根据其使用选择器的状态进行更改。

如果您的选择器是这样定义的(假设存在适当的drawable,当然):

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_focused="true"
          android:drawable="@drawable/list_item_pressed" />
    <item android:state_pressed="true"
          android:drawable="@drawable/list_item_pressed" />
    <item android:state_selected="true"
          android:state_activated="true"
          android:drawable="@drawable/list_item_selected" />
    <item android:state_activated="true"
          android:drawable="@drawable/list_item_selected" />
    <item android:state_selected="true"
          android:drawable="@android:color/black" />
    <item android:drawable="@android:color/transparent" />
</selector>

然后将GridView的选择模式设置为单个选择:

<GridView
   ...
   android:choiceMode="singleChoice" />

这让操作系统可以为您记住在列表中选择了哪个位置,然后在您点击另一个位置时为您清除

答案 2 :(得分:1)

嗯,这可能不能很好地回答你的问题,但我做了类似的事情。基本上,我将项目添加到表格中,并且需要有一个与项目关联的删除按钮。单击删除按钮时,只需从表中删除该项。这可以根据您的需要进行调整,而不是删除单击的项目,它会找到上一个项目,取消它,然后突出显示然后重新点击的项目。

所以我所做的就是给按钮本身一个标签(显然它们必须是唯一的)。单击按钮时,将其标记保存在sharedPreference之类的内容中供以后参考。然后,当单击一个新按钮时,只需找到带有先前单击的标记的按钮,并取消标记它所在的行,然后标记新单击按钮的行。这是我使用的代码(对不起,变量名称很糟糕,我实际上在一个从未发布的测试应用程序中工作,所以我没有给他们更好的名字):

        //Previous button clicked
        String id = <get this from wherever you choose to store it>
        // create a new TableRow
        TableRow row = new TableRow(getApplicationContext());

        TextView t = new TextView(getApplicationContext());
        t.setTextColor(Color.BLACK);
        t.setText(unique);

        Button b = new Button(getApplicationContext());
        b.setOnClickListener(new Button.OnClickListener() {

            public void onClick(View v) 
            { 
                for(int i = 0; i < table.getChildCount(); i++)
                {          
                    TableRow row = (TableRow) table.getChildAt(i);                        
                    Button bt = (Button) row.getChildAt(1);
                    TextView view  = (TextView)row.getChildAt(0);

                    if( id.equals(v.getTag())) //they match, so this is the button that was previously clicked
                    {
                        //Put your code here to unclick the previous button and mark the new one as clicked.                            

                    }
                }  
            }
        });   

        b.setText(R.string.removeButtonText);
        b.setTag(t.getText().toString());

        /***BE SURE TO SAVE THE NEW BUTTON TAG (t.getText().toString()) SOMEWHERE LIKE A SHARED PREFERENCE****/
        //saving the tag

        //add the row to the table                
        row.addView(t);
        row.addView(b);        
        // add the TableRow to the TableLayout
        table.addView(row,new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

同样,我不怀疑这是你正在寻找的确切答案,但也许它会给你一个尝试的想法。希望这有一定道理,如果没有,请随时要求澄清。对不起,如果它也偏离了基地。