使用 RelativeLayout 在 GridView 中获取复选框状态

get checkbox state inside GridView with RelativeLayout

我有带有更多复选框的 GridView,我需要知道复选框状态是什么。正如 post 末尾所述,当我在我的 XML.

中插入 RelativeLayout、ImageView 和 TextView 时收到错误消息

我收到了这个日志:

 05-05 22:03:29.375: E/AndroidRuntime(3443): FATAL EXCEPTION: main
 05-05 22:03:29.375: E/AndroidRuntime(3443): Process:       com.kirolm.instalacionesdep, PID: 3443
 05-05 22:03:29.375: E/AndroidRuntime(3443):     java.lang.NullPointerException
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.kirolm.instalacionesdep.search.BuscarInstalacionesActividadFragment.ge    tItemCheked(BuscarInstalacionesActividadFragment.java:218)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.kirolm.instalacionesdep.search.BuscarInstalacionesActividadFragment.on    OptionsItemSelected(BuscarInstalacionesActividadFragment.java:123)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.app.Fragment.performOptionsItemSelected(Fragment.java:1806)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.app.FragmentManagerImpl.dispatchOptionsItemSelected(FragmentManager.java:1972)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.app.Activity.onMenuItemSelected(Activity.java:2603)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1065)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:741)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:884)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.ActionMenuView.invokeItem(ActionMenuView.java:546)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:115)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.view.View.performClick(View.java:4445)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.view.View$PerformClick.run(View.java:18446)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.os.Handler.handleCallback(Handler.java:733)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.os.Handler.dispatchMessage(Handler.java:95)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.os.Looper.loop(Looper.java:136)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at android.app.ActivityThread.main(ActivityThread.java:5146)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at java.lang.reflect.Method.invokeNative(Native Method)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at java.lang.reflect.Method.invoke(Method.java:515)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
 05-05 22:03:29.375: E/AndroidRuntime(3443):    at dalvik.system.NativeStart.main(Native Method)

我有这个XML:

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

    <RelativeLayout 
android:layout_width="match_parent"
android:layout_height="wrap_content" 
android:gravity="center">

            <ImageView
        android:id="@+id/buscar_instalaciones_actividad_fragment_imageview_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true" 
        android:scaleType="center"
        android:src="@drawable/header_buscar_actividad" />

            <TextView
        android:id="@+id/buscar_instalaciones_actividad_fragment_tv_titulo_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center_horizontal"
                      android:text="@string/buscar_instalaciones_actividad_fragment_titulo_header"
                      android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

    <GridView
        android:id="@+id/buscar_instalaciones_actividad_fragment_gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="0dp"
        android:numColumns="4"
        android:stretchMode="columnWidth"
        android:verticalSpacing="0dp" >
    </GridView>

这是我的 getItemChecked() 方法:

    public ArrayList<String> getItemCheked(){
    ArrayList<String> checkResultArray = new ArrayList<String>();

    int count = grid.getAdapter().getCount();
    for(int i = 0; i < count; i++){
        RelativeLayout itemLayout = (RelativeLayout)grid.getChildAt(i);
        CheckBox chb = (CheckBox) itemLayout.findViewById(R.id.buscar_instalaciones_actividad_activity_grid_item_chb);
        if(chb.isChecked()){
            String valor = (String) chb.getTag();
            checkResultArray.add(valor);
            Log.e("Checking", "BuscarInstalacionesActividadActivity: El boton pulsado es: "+valor );
        }
    }
    return checkResultArray;
}

第218行是这样的:

CheckBox chb = (CheckBox) itemLayout.findViewById(R.id.buscar_instalaciones_actividad_activity_grid_item_chb);

如果我在 xml 中删除它,它运行正常,但我需要 RelativeLayout、ImageView 和 textView。

        <RelativeLayout 
android:layout_width="match_parent"
android:layout_height="wrap_content" 
android:gravity="center">
            <ImageView
        android:id="@+id/buscar_instalaciones_actividad_fragment_imageview_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true" 
        android:scaleType="center"
        android:src="@drawable/header_buscar_actividad" />

                  <TextView
                      android:id="@+id/buscar_instalaciones_actividad_fragment_tv_titulo_header"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_centerHorizontal="true"
                      android:layout_centerVertical="true"
                      android:gravity="center_horizontal"
                      android:text="@string/buscar_instalaciones_actividad_fragment_titulo_header"
                      android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

编辑 我忘了,我在自定义适配器中膨胀了复选框。

这是我的 Adapter 中的 getView 方法。

    public View getView(int position, View convertView, ViewGroup parent) {

    View grid;

    if (convertView == null) {   
    grid = new View(context);
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    grid = inflater.inflate(R.layout.buscar_instalaciones_actividad_activity_grid_check_item, null);               



    }  else {
        grid = (View) convertView;

    }        
    tv = (TextView) grid.findViewById(R.id.buscar_instalaciones_actividad_activity_grid_item_text);
    tv.setText(items.get(position).getNombreActividad());
    chb = (CheckBox) grid.findViewById(R.id.buscar_instalaciones_actividad_activity_grid_item_chb);

    chb.setTag(items.get(position).getTipoActividad());

    String fotoActividad = items.get(position).getFotoActividad();
    fotoActividad = "checkbox_"+fotoActividad;
    int imagenParaMostrar = context.getResources().getIdentifier(fotoActividad, "drawable", context.getPackageName());
    if(imagenParaMostrar == 0){

        fotoActividad = "checkbox_actividad_sinfoto";
        imagenParaMostrar = context.getResources().getIdentifier(fotoActividad, "drawable", context.getPackageName());
        Log.e("Checking", "CheckableImageGridActividadesAdapter. El nombre de la imagen es: "+fotoActividad);

    }
    chb.setButtonDrawable(imagenParaMostrar);


    tv.setSelected(false);
    View.OnClickListener handler = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            v.setSelected(true);
        }
    };
    tv.setOnClickListener(handler);

    return grid; 
    }

这是buscar_instalaciones_actividad_activity_grid_check_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/album_item"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" 
android:background="@color/white"
android:padding="10dp">

<CheckBox
    android:id="@+id/buscar_instalaciones_actividad_activity_grid_item_chb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"/>

<TextView
    android:id="@+id/buscar_instalaciones_actividad_activity_grid_item_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/buscar_instalaciones_actividad_activity_grid_item_chb"
    android:layout_centerHorizontal="true"
    android:ellipsize="marquee"
    android:singleLine="true"
    android:text="detalles"
    android:textColor="@color/Black"
    android:textSize="16sp"/>

   </RelativeLayout>

因为你使用 grid.getAdapter().getCount() 我相信你想要的是 grid.getAdapter().getItem(i) 而不是 grid.getChildAt(i)。由于 grid.getChildAt(i) 似乎 return null 这应该是您遇到问题的原因。

所以只需替换:

RelativeLayout itemLayout = (RelativeLayout)grid.getChildAt(i);

作者:

RelativeLayout itemLayout = (RelativeLayout)grid.getAdapter().getItem(i);

编辑:

对不起,我错了,忘了getItem 不是return视图而是对应的对象。但也许您可以在复选框上设置一个 OnCheckedChangeListener 来更新项目中的布尔值 'Actividad' 并通过这种方式简单地获取布尔值:

boolean b = ((Actividad)grid.getAdapter().getItem(i)).getterForTheBoolean();

在获取视图中:

chb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
//....
items.get(position).setterForTheBoolean(isChecked);

});