Android GridView适配器.getView()未正确设置选定状态
我有一个GridView,我正在填充ArrayAdapter的一个自定义子类。这个适配器返回我定制为可选择的按钮(请参阅)。到目前为止,这是有效的,单击按钮可以选择它们(在选择器背景下可见) 问题是:我无法从一开始就将这些按钮设置为选定状态。当我第一次启动视图时,它们只是显示为未选中 我创建了一个简单的测试项目来说明这个问题:Android GridView适配器.getView()未正确设置选定状态,android,button,gridview,adapter,selected,Android,Button,Gridview,Adapter,Selected,我有一个GridView,我正在填充ArrayAdapter的一个自定义子类。这个适配器返回我定制为可选择的按钮(请参阅)。到目前为止,这是有效的,单击按钮可以选择它们(在选择器背景下可见) 问题是:我无法从一开始就将这些按钮设置为选定状态。当我第一次启动视图时,它们只是显示为未选中 我创建了一个简单的测试项目来说明这个问题: package com.example.buttonselection; import android.app.Activity; import android.con
package com.example.buttonselection;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
public class MainActivity extends Activity {
public class SelectButtonAdapter extends ArrayAdapter<String> {
public SelectButtonAdapter(Context context) {
super(context, 0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String name = getItem(position);
View rowView = convertView;
if (rowView == null || !(rowView instanceof Button)) {
rowView = new Button(getContext());
((Button)rowView).setOnClickListener(new OnClickListener() {
public void onClick(View button) {
if (button.isSelected()){
button.setSelected(false);
} else {
button.setSelected(true);
}
}
});
}
Button button = (Button)rowView;
button.setText(name);
button.setBackgroundResource(R.drawable.button_selection);
button.setSelected(true); // this does not work
return button;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView grid = (GridView)findViewById(R.id.gridview);
SelectButtonAdapter adapter = new SelectButtonAdapter(this);
adapter.add("One");
adapter.add("Two");
adapter.add("Three");
grid.setAdapter(adapter);
}
}
package com.example.buttonselection;
导入android.app.Activity;
导入android.content.Context;
导入android.os.Bundle;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.Button;
导入android.widget.GridView;
公共类MainActivity扩展了活动{
公共类SelectButtonAdapter扩展了ArrayAdapter{
公共选择按钮适配器(上下文){
超级(上下文,0);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
字符串名称=getItem(位置);
视图行视图=转换视图;
if(rowView==null | |!(rowView instanceof按钮)){
rowView=新建按钮(getContext());
((按钮)rowView.setOnClickListener(新的OnClickListener(){
公共void onClick(查看按钮){
if(button.isSelected()){
按钮。选择设置(假);
}否则{
按钮。设置选择(真);
}
}
});
}
按钮按钮=(按钮)行视图;
button.setText(名称);
按钮。setBackgroundResource(R.可绘制。按钮选择);
button.setSelected(true);//这不起作用
返回按钮;
}
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView网格=(GridView)findViewById(R.id.GridView);
SelectButtonAdapter=新建SelectButtonAdapter(此);
适配器。添加(“一”);
添加(“两个”);
添加(“三”);
设置适配器(适配器);
}
}
因此,我甚至无法恢复使用onSaveInstanceState保存的按钮的状态。如何解决或解决此问题
我非常感谢你的帮助
编辑:这是我的button_selection.xml,不过这应该可以,因为以后选择按钮也可以
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="@color/bet_button_pressed" />
<stroke
android:width="2dip"
android:color="@color/white" />
</shape>
</item>
<item android:state_selected="true">
<shape>
<solid android:color="@color/bet_button_selected" />
<stroke
android:width="2dip"
android:color="@color/white" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="90"
android:startColor="@color/bet_button_dark_green"
android:endColor="@color/bet_button_light_green"
android:centerX="0.5"
android:centerY="0.5" />
<stroke
android:width="2dip"
android:color="@color/white" />
</shape>
</item>
</selector>
我找到了解决此错误的方法。我只是在外部存储一个按钮是否被选中,并覆盖按钮的ondraw方法,以便在每次绘制时设置正确的状态。这还有一个额外的优点,即选择可以更容易地持久化 这里是解决方法(只是一个简单的概念证明,我的生产代码更复杂):
package com.example.buttonselection;
导入java.util.HashSet;
导入java.util.Set;
导入android.app.Activity;
导入android.content.Context;
导入android.graphics.Canvas;
导入android.os.Bundle;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.view.ViewGroup;
导入android.widget.ArrayAdapter;
导入android.widget.Button;
导入android.widget.GridView;
公共类MainActivity扩展了活动{
公共类SelectButtonAdapter扩展了ArrayAdapter{
公共选择按钮适配器(上下文){
超级(上下文,0);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
字符串名称=getItem(位置);
视图行视图=转换视图;
if(rowView==null | |!(rowView instanceof按钮)){
rowView=新建按钮(getContext()){
@凌驾
受保护的void onDraw(画布){
setSelected(selectedButtons.contains(getText()));
super.onDraw(帆布);
}
};
((按钮)rowView.setOnClickListener(新的OnClickListener(){
公共void onClick(查看按钮){
字符串文本=((按钮)按钮).getText().toString();
如果(所选按钮。包含(文本)){
选择按钮。删除(文本);
}否则{
选择按钮。添加(文本);
}
按钮。无效();
}
});
}
按钮按钮=(按钮)行视图;
button.setText(名称);
按钮。setBackgroundResource(R.可绘制。按钮选择);
返回按钮;
}
}
private Set selectedButtons=new HashSet();
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView网格=(GridView)findViewById(R.id.GridView);
SelectButtonAdapter=新建SelectButtonAdapter(此);
适配器。添加(“一”);
添加(“两个”);
添加(“三”);
设置适配器(适配器);
//这将从开始选择第一个按钮
选择按钮。添加(“一”);
}
}
旁注:
有人会认为,4.1版API不会包含如此明显的bug。在这方面浪费的时间令人沮丧,并没有激励我们为这个系统开发更多的东西。我很抱歉
package com.example.buttonselection;
import java.util.HashSet;
import java.util.Set;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
public class MainActivity extends Activity {
public class SelectButtonAdapter extends ArrayAdapter<String> {
public SelectButtonAdapter(Context context) {
super(context, 0);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String name = getItem(position);
View rowView = convertView;
if (rowView == null || !(rowView instanceof Button)) {
rowView = new Button(getContext()) {
@Override
protected void onDraw(Canvas canvas) {
setSelected(selectedButtons.contains(getText()));
super.onDraw(canvas);
}
};
((Button)rowView).setOnClickListener(new OnClickListener() {
public void onClick(View button) {
String text = ((Button)button).getText().toString();
if(selectedButtons.contains(text)) {
selectedButtons.remove(text);
} else {
selectedButtons.add(text);
}
button.invalidate();
}
});
}
Button button = (Button)rowView;
button.setText(name);
button.setBackgroundResource(R.drawable.button_selection);
return button;
}
}
private Set<String> selectedButtons = new HashSet<String>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView grid = (GridView)findViewById(R.id.gridview);
SelectButtonAdapter adapter = new SelectButtonAdapter(this);
adapter.add("One");
adapter.add("Two");
adapter.add("Three");
grid.setAdapter(adapter);
// this selects the first button from the start
selectedButtons.add("One");
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
String name = getItem(position);
View rowView = convertView;
if (rowView == null || !(rowView instanceof Button)) {
rowView = new Button(getContext());
((Button)rowView).setOnClickListener(new OnClickListener() {
public void onClick(View button) {
if (button.isSelected()){
button.setSelected(false);
} else {
button.setSelected(true);
}
}
});
}
Button button = (Button)rowView;
button.setText(name);
button.setBackgroundResource(R.drawable.button_selection);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
button.setSelected(true);
}
}, 50);
return button;
}