我删除了项目中的几乎所有代码,以找到隐藏的bug。有一个包含框架布局的GridView,并且布局包含CheckBox。 但是我无法检查第一个复选框。(其他人工作)
最后(我想)我找到了答案。但这太奇怪了。当我删除回收convertView的行时,错误消失了。我改变了:
if(convertView == null) {
layout = (FrameLayout)View.inflate(maincon, R.layout.taste_brand, null);
} else {
layout = (FrameLayout) convertView;
}
到FrameLayout layout = (FrameLayout)View.inflate(maincon, R.layout.taste_brand, null);
。
我真的不知道这种情况。我附上了休息代码。
TasteGridAdapter.java:
public class TasteGridAdapter extends BaseAdapter {
Context maincon;
public TasteGridAdapter(Context context) {
maincon = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
FrameLayout layout;
if(convertView == null) {
layout = (FrameLayout)View.inflate(maincon, R.layout.taste_brand, null);
} else {
layout = (FrameLayout) convertView;
}
layout.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
return layout;
}
@Override
public int getCount() {
return 3;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
}
onCreate of the activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.taste);
TasteGridAdapter adapter = new TasteGridAdapter(this);
GridView grid = (GridView) findViewById(R.id.taste_grid);
grid.setAdapter(adapter);
}
taste.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<GridView
android:layout_weight="1"
android:id="@+id/taste_grid"
android:layout_width="match_parent"
android:layout_height="0dip"
android:columnWidth="87dip"
android:gravity="center"
android:horizontalSpacing="4dip"
android:numColumns="auto_fit"
android:padding="2dip"
android:stretchMode="columnWidth"
android:verticalSpacing="4dip" />
</LinearLayout>
taste_brand.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="87dp"
android:layout_height="58dp">
<CheckBox
android:id="@+id/taste_brand_check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</FrameLayout>
答案 0 :(得分:4)
我遇到了GridView中第一个项目的类似问题。要解决问题,请删除“新”关键字,然后更改现有的视图LayoutParams:
LayoutParams lp = layout.getLayoutParams();
lp.height = someHeight;
...对这些LayoutParams做点什么。这个黑客解决了我的问题。结论,尽量避免通过“new”创建新的LayoutParams对象。
答案 1 :(得分:3)
layout.setLayoutParams(new GridView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
将此行置于此状态
if(convertView == null){
}
我遇到了同样的问题,但我尝试了这个,它的工作对我来说。我希望它也适合你。
答案 2 :(得分:1)
您遇到的问题与Android在ListView
,GridView
等中回收视图的方式有关。您提到您的第一个复选框无法检查,而其他复选框仍然有效。我想你会注意到其他人只有出现才能正常工作,因为你没有正确处理回收。
你的行
的原因FrameLayout layout = (FrameLayout)View.inflate(maincon, R.layout.taste_brand, null);
似乎解决了这个问题,因为现在每次使用时都会再次膨胀视图。我承认,当我开始这样做时,重新膨胀视图似乎是最好的解决方案;然而,它完全违背了回收的目的,并且你失去了获得的所有性能优势。
现在来解决你的问题:
首先,我强烈建议您将ViewHolder
模式与BaseAdapter
结合使用。有关详细信息,请参见here。
其次,您应该创建一个布尔数组来匹配GridView
中的所有项目,并使用它来确定是否应该单击某个项目。在复选框侦听器中设置相应布尔值的值,并在getView(..)
中使用该值来选中或取消选中该特定框。
总体上更好的解决方案可能是在适配器类中使用模型的数组(或列表),每个模型都包含可通过isChecked
和setChecked(boolean)
访问的布尔字段。同样,您可以在getView(..)
内使用此功能来正确显示视图并更改复选框OnCheckedChangeListener
中的值。
希望有所帮助。
答案 3 :(得分:0)
正如jonstaff所说,这与View回收有关。
如果您正在为GridView View绑定使用自定义Adapter类,请尝试修改其getView()方法以始终实例化 new 视图,如:
public View getView(int position, View convertView, ViewGroup parent){
SomeView v = new SomeView(context); // <--- here
...
return v;
}
相反典型的:
public View getView(int position, View convertView, ViewGroup parent){
SomeView v;
if (convertView == null)
v = new SomeView (context);
else
v= (SomeView)convertView;
...
return v;
}
这可能会影响性能,但它解决了一个小型GridView按钮的问题。