【发布时间】:2015-02-16 01:18:52
【问题描述】:
我一直在实现一个应用程序,我在其中使用包含三个项目(图像视图、文本视图和复选框)的列表视图,列表视图工作正常(向下滚动时除外,它不会保持视图的状态)但我的问题为什么当我触摸操作栏的图标时,它会完全改变复选框的状态?
这是我的应用程序的正常行为:
当我点击一个复选框时,它会将状态更改为选中
但是当我按下工具栏的操作按钮时,会发生这种情况:
如果你没有点击任何动作,点击其他地方隐藏动作菜单,复选框的状态变为正常状态
我不知道为什么会发生这种情况,但我认为它必须与片段的生命周期有关
你能帮帮我吗?
这是这个片段的代码:
@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);
}
我在这个片段中有一个用于从 Internet 检索 ListView 数据的 Asystask
@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();
}
}
这是适配器的代码:
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;
}
}
但实际上我认为问题根本不在于适配器,因为当您单击列表视图中的一个项目时,它会打开另一个带有详细列表的片段(该片段只包含文本视图和一个复选框)。这是问题的截图:
这是我点击设置菜单时发生的事情
奇怪的是,如果你点击抽屉的汉堡图标,复选框就会处于正常状态(没有任何变化)
这是最后一张截图的片段:
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);
}
}
编辑适配器类
我一直在苦苦挣扎,我已经解决了第一个问题。当回收视图更改行时,它会丢失复选框的状态并导致复选框不断更改其状态。我通过创建一个新的 Establecimiento 类来保存所有数据,然后在调用适配器之前创建了一个 ArrayList,将状态与其他值一起保存。我已经更新了我的适配器类以反映这种情况,现在复选框始终保持其状态,但是当您单击选项菜单并且在发生这种情况时弹出选项菜单时,复选框会更改它们的状态,然后当您单击其他位置时它会恢复正常状态
【问题讨论】:
-
这听起来像是适配器的问题。你能发布它的代码(特别是
getView())吗? -
谢谢@matiash,但我不这么认为,因为在其他视图(没有列表视图)中它的行为完全相同。我已经用更多信息编辑了我的问题。
-
if (sharedP.getBoolean(String.valueOf(position), false))您在共享首选项中的哪个位置保存此值? -
我认为当您选中或取消选中复选框时,您会有一些监听器。仅监听 checkbox 而不是整个 listview 项
-
@GPRathour 我为屏幕截图的最后一个片段添加了类,该片段没有列表视图并且仍然具有相同的行为。我认为您必须是对的,但我还没有解决方法..
标签: android checkbox android-listview savestate