单击操作栏项目复选框时,请更改其状态

时间:2014-12-17 13:17:58

标签: android checkbox android-listview savestate

我一直在实现一个应用程序,我使用带有三个项目的列表视图(图像视图,文本视图和复选框),listview工作正常(除了向下滚动时不保持视图的状态)但是我的问题是,为什么当我触摸操作栏的图标时,它会完全改变复选框的状态?

这是我的应用的正常行为:

enter image description here

当我点击一个复选框时,它会将状态更改为已选中

enter image description here

但是,当我按下工具栏的操作按钮时,会发生以下情况:

enter image description here

如果您没有点击任何操作,请单击其他位置以隐藏操作菜单,复选框的状态将变为正常状态

我并不确切地说为什么会这样,但我认为它必须是关于片段生命周期的事情

你能帮帮我吗?

这是此片段的代码:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        establecimientosList = new ArrayList<HashMap<String, String>>();
        rootView = inflater.inflate(R.layout.fragment_establecimientos,
                container, false);

        mDrawerToggle = new ActionBarDrawerToggle(getActivity(), null, 0, 0);

        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
        // ListView lv = getListView();

        if (savedInstanceState == null) {
            new GetEstablecimientos().execute();
        }

        ListView lv = getListView();
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                // TODO Auto-generated method stub
                Fragment fragment = null;
                fragment = new MostrarEstablecimientoFragment();

                // mDrawerToggle.setDrawerIndicatorEnabled(false);
                Bundle bundle = new Bundle();
                bundle.putSerializable("HashMap",
                        establecimientosList.get(arg2));
                bundle.putInt(ID, arg2);
                fragment.setArguments(bundle);

                android.app.FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction()
                        .replace(R.id.content_frame, fragment)
                        .addToBackStack(null).commit();
                ((ActionBarActivity) getActivity()).getSupportActionBar()
                        .setTitle(
                                establecimientosList.get(arg2).get(TAG_NOMBRE));

            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub;
        mDrawerToggle.setDrawerIndicatorEnabled(true);
        return super.onOptionsItemSelected(item);
    }

我在这个片段里面有一个Asystask,用于从Internet上检索ListView数据

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();
            /**
             * Updating parsed JSON data into ListView
             * */
            if (!establecimientosList.isEmpty()) {
                LazyAdapter mAdapter = new LazyAdapter(getActivity(),
                        establecimientosList, "RobotoTTF/Roboto-Thin.ttf");
                setListAdapter(mAdapter);
            } else {
                TextView textoError = (TextView) rootView
                        .findViewById(R.id.textViewEstablecimientoError);
                textoError.setVisibility(View.VISIBLE);
                ListView lv = getListView();
                lv.setVisibility(View.GONE);
                Toast.makeText(getActivity(), "Error", Toast.LENGTH_LONG)
                        .show();
            }
        }

enter image description here

这是适配器的代码:

  public class LazyAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList<HashMap<String, String>> data;
    private static LayoutInflater inflater = null;
    public ImageLoader imageLoader;
    private Typeface tf;

    private final ArrayList<Establecimiento> listEstab;

    private SharedPreferences sharedP;

    public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d,
            String font, ArrayList<Establecimiento> posEstablecimiento) {
        activity = a;
        data = d;
        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
        tf = Typeface.createFromAsset(a.getAssets(), font);
        sharedP = a.getSharedPreferences(PREFENCIAS_FAVORITOS,
                Context.MODE_PRIVATE);
        listEstab = posEstablecimiento;
    }

    public int getCount() {
        return data.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        final int pos = position;
        if (convertView == null) // {
            vi = inflater.inflate(R.layout.list_item, null);

        TextView nombre = (TextView) vi
                .findViewById(R.id.nombreEstablecimientoList);
        TextView descripcion = (TextView) vi.findViewById(R.id.descripcionList);
        TextView localidad = (TextView) vi.findViewById(R.id.localidadList);
        // thumb image
        ImageView thumb_image = (ImageView) vi.findViewById(R.id.list_image);
        CheckBox checkFav = (CheckBox) vi.findViewById(R.id.imageList);

        HashMap<String, String> establecimiento = new HashMap<String, String>();
        establecimiento = data.get(position);

        // Setting all values in listview
        nombre.setText(establecimiento.get(TAG_NOMBRE));
        descripcion.setText(establecimiento.get(TAG_DESCRIPCION));
        localidad.setText(establecimiento.get(TAG_LOCALIDAD));
        imageLoader.DisplayImage(establecimiento.get(TAG_IMAGEN_TIPO),
                thumb_image);
        checkFav.setChecked(listEstab.get(position).getFavorito());
        checkFav.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                // Actualizo lo que vale en las variables de entorno
                sharedP.edit()
                        .putBoolean(
                                String.valueOf(listEstab.get(pos).getId()),
                                !sharedP.getBoolean(String.valueOf(listEstab
                                        .get(pos).getId()), false)).commit();

                listEstab.get(pos).setFavorito(
                        !listEstab.get(pos).getFavorito());
                Toast.makeText(activity,
                        String.valueOf(listEstab.get(pos).getFavorito()),
                        Toast.LENGTH_SHORT).show();
            }
        });
        checkFav.setFocusable(false);

        return vi;

    }
}

但实际上我并不认为问题必须与适配器有关,因为当你点击listview中的一个项目时,它会打开另一个带有详细列表的片段(这个片段只包含textviews和一个复选框)。这是问题的屏幕截图:

enter image description here

这是我点击设置菜单时发生的事情

enter image description here

奇怪的是,如果你点击抽屉的汉堡包图标,复选框就会显示正常状态(没有任何变化)

这是最后一个屏幕截图的片段:

public class MostrarEstablecimientoFragment extends Fragment {

    SharedPreferences editor;

    HashMap<String, String> establecimiento = new HashMap<String, String>();

    CheckBox favButton;

    public MostrarEstablecimientoFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);
        // ((ActionBarActivity) getActivity()).getSupportActionBar()
        // .setDisplayHomeAsUpEnabled(true);
        editor = getActivity().getSharedPreferences(PREFENCIAS_FAVORITOS,
                Context.MODE_PRIVATE);
    }

    @SuppressWarnings("unchecked")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(
                R.layout.fragment_mostrar_establecimiento, container, false);

        getActivity().setTitle("Mostrar información");

        favButton = (CheckBox) rootView.findViewById(R.id.favorite_button);

        if (getArguments() != null) {

            establecimiento = (HashMap<String, String>) getArguments()
                    .getSerializable("HashMap");

            Boolean isFav = editor.getBoolean(establecimiento.get(TAG_ID),
                    false);

            if (isFav) {
                if (favButton.isChecked() == false)
                    favButton.setChecked(true);
            }

            TextView tvTitle = (TextView) rootView
                    .findViewById(R.id.nameEstablecimiento);
            tvTitle.setText(establecimiento.get(TAG_NOMBRE));
            TextView tvHorario = (TextView) rootView
                    .findViewById(R.id.textViewHorario);
            tvHorario.setText(establecimiento.get(TAG_HORARIO));
            TextView tvDescp = (TextView) rootView
                    .findViewById(R.id.textViewDescp);
            tvDescp.setText(establecimiento.get(TAG_DESCRIPCION));
            TextView tvDirec = (TextView) rootView
                    .findViewById(R.id.textViewDirec);
            tvDirec.setText(establecimiento.get(TAG_DIRECCION));
            TextView tvLocal = (TextView) rootView
                    .findViewById(R.id.textViewLocalidad);
            tvLocal.setText(establecimiento.get(TAG_LOCALIDAD));
            TextView tvProv = (TextView) rootView
                    .findViewById(R.id.textViewProv);
            tvProv.setText(establecimiento.get(TAG_PROVINCIA));
            TextView tvCodPostal = (TextView) rootView
                    .findViewById(R.id.textViewCodigo);
            tvCodPostal.setText(establecimiento.get(TAG_CODIGOPOSTAL));
            TextView tvEmail = (TextView) rootView
                    .findViewById(R.id.textViewWeb);
            tvEmail.setText(establecimiento.get(TAG_EMAIL));
            TextView tvTlf1 = (TextView) rootView
                    .findViewById(R.id.textViewTlf1);
            tvTlf1.setText(establecimiento.get(TAG_TLF1));
            TextView tvTlf2 = (TextView) rootView
                    .findViewById(R.id.textViewTlf2);
            tvTlf2.setText(establecimiento.get(TAG_TLF2));
        }

        favButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                // favButton.setActivated(true);

                editor.edit().putBoolean(establecimiento.get(TAG_ID),
                        !editor.getBoolean(establecimiento.get(TAG_ID), false)).commit();

            }
        });
        return rootView;

    }

    @Override
    public void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        editor.edit().commit();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        switch (item.getItemId()) {
        case (R.id.action_back):
            getFragmentManager().popBackStackImmediate();
            break;

        default:
            getActivity().onBackPressed();
            break;
        }
        return super.onOptionsItemSelected(item);

    }
}

enter image description here


EDIT AdapterClass

我一直在努力,我已经解决了第一个问题。当循环视图更改行时,它会丢失复选框的状态,并导致复选框不断更改其状态。我通过创建一个新的Establecimiento类来保存所有数据,然后在调用适配器之前我创建了一个ArrayList,保存了其他值的状态。我已经更新了我的适配器类以反映这种情况,现在复选框始终保持其状态,但是当您单击选项菜单并且弹出选项菜单时,复选框会更改其状态,然后当您单击其他位置时恢复正常状态

2 个答案:

答案 0 :(得分:0)

这里有一个问题:

    if (sharedP.getBoolean(String.valueOf(position), false)) {
        checkFav.setChecked(true);
    }

您将检查设置为true,但永远不会为false。这意味着当视图被回收然后重新用于不同的行时,它们将显示为收藏夹,即使它们不是。

这应该是这样的:

    boolean isFav = sharedP.getBoolean(String.valueOf(position), false);
    checkFav.setChecked(isFav);

答案 1 :(得分:0)

嗯,我想我终于知道发生了什么......我使用了一个自定义的可绘制的星形图像(有两个图像,一个用于检查,一个用于未检查)这是我的明星可绘制的:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- Enabled states -->

    <item android:state_checked="true" android:state_window_focused="false"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_not_important" />
    <item android:state_checked="false" android:state_window_focused="false"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_important_cb" />

    <item android:state_checked="true" android:state_pressed="true"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_important_cb" />
    <item android:state_checked="false" android:state_pressed="true"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_not_important" />

    <item android:state_checked="true" android:state_focused="true"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_important_cb" />
    <item android:state_checked="false" android:state_focused="true"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_not_important" />

    <item android:state_checked="false"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_not_important" />
    <item android:state_checked="true"
          android:state_enabled="true"
          android:drawable="@drawable/ic_action_important_cb" />


</selector>

我只是预感我已经删除了我的自定义图像而是改为使用@ android / drawable =“btn_star”(我不喜欢它,因为它是一个非常古老的设计并打破了我的应用程序的整个外观)但是有了这个资源,现在的行为是完全正常的,所以我觉得我的自定义drawable出了点问题,但找不到它是什么