无法在GridView中启用/禁用可单击的TextView

时间:2011-05-28 21:53:20

标签: android

我有一个GridView,可点击TextViews作为GridView项目,使用适配器(TextViews用作按钮)。当我单击TextView时,我想在GridView中禁用所有TextView - 禁用用户无法再单击它们。我做的是这个:

    private void toggleButtonsState(boolean enabled)
    {
        for (int i = 0; i < this.gridview.getChildCount(); i++)
        {
            this.gridview.getChildAt(i).setEnabled(enabled);            
        }
    }   

但是,即使使用enabled == false调用此代码,仍会启用按钮。这有什么不对?如何禁用其他TextView?谢谢!


我做了你所说的并直接实现了BaseAdapter。但是,这两个方法永远不会被调用:既不是在开头也不是在notifyDataSetChanged。真的不知道发生了什么事。这是代码:

public class TextViewAdapter extends BaseAdapter implements View.OnClickListener  {

@Override
public boolean areAllItemsEnabled() {
    // TODO Auto-generated method stub
    return super.areAllItemsEnabled();
}

@Override
public boolean isEnabled(int position) {
    // TODO Auto-generated method stub
    return super.isEnabled(position);
}

protected Context mContext;         

public TextViewAdapter(Context c)
{           
    this.mContext = c;      
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return DbManager.getInstance(mContext).getCategoryCount(true);
}

@Override
public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return arg0;
}


@Override
public long getItemId(int arg0) {
    // TODO Auto-generated method stub
    return 0;
}

@Override
public View getView(int arg0, View convertView, ViewGroup arg2) {           

    final LinearLayout linearLayout;          

    if (convertView == null) {  // if it's not recycled, initialize some attributes

        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        linearLayout = (LinearLayout)inflater.inflate(R.layout.settings_timer_textview, null);
        TextView textView = (TextView)linearLayout.findViewById(R.id.timer_textview);           
        textView.setOnClickListener(this);                          

    } else {
        linearLayout = (LinearLayout) convertView;
    }


    setCategoryView(linearLayout, arg0);    
    setControls(linearLayout, arg0);

    return linearLayout;

}

private void setControls(LinearLayout linearLayout, int index)
{
    TextView textView = (TextView)linearLayout.findViewById(R.id.timer_textview);
    Category category = getCategory(index);
    textView.setTag(category);                  
    textView.setText(category.getName());            
    textView.setTextColor(TimeManagerActivity.getForeColorByBrightness(category.getColor()));           
    textView.setBackgroundDrawable(createTextViewDrawable(category.getColor()));

    CheckBox checkbox = (CheckBox)linearLayout.findViewById(R.id.timer_checkbox);       
    checkbox.setChecked(category.getEnabled() != 0);        
    checkbox.setTag(textView.getText().toString());
}

protected Category getCategory(int index)
{
    return DbManager.getInstance(this.mContext).getCategoryByIndex(index, true);
}

protected void setCategoryView(View view, int index)
{
    // TODO Auto-generated method stub      

    TextView textView = (TextView)view.findViewById(R.id.timer_textview);       
    textView.setGravity(Gravity.CENTER);
    textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 40));

    CheckBox checkbox = (CheckBox)view.findViewById(R.id.timer_checkbox);
    checkbox.setVisibility(View.GONE);
}

@Override
public void onClick(View arg0)
{       
    // TODO Auto-generated method stub      
    this.notifyDataSetChanged();
}   

public void update()
{
    this.notifyDataSetChanged();
}

private StateListDrawable createTextViewDrawable(int color)
{               
    // Create a gradient for the button. Height is hardcoded to 30 (I don't know the height beforehand). 
    // I wish I could set the gradient aligned to the bottom of the button.
    final Shader shader = new LinearGradient(0, 0, 0, 0,
        new int[] { color, color },
        null, Shader.TileMode.MIRROR);          

    float[] roundedCorner = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
    ShapeDrawable normal = new ShapeDrawable(new RoundRectShape(roundedCorner, null, null));

    normal.getPaint().setShader(shader);
    normal.setPadding(3, 3, 3, 3);

    // Create a state list (I suppressed settings for pressed).             
    StateListDrawable state_list = new StateListDrawable();
    state_list.addState(new int[] { }, normal);

    return state_list;
}

}


这是我的TextViewAdapter派生的类,它本身派生自BaseAdapter。我的TextViewAdapter只是定义了一些抽象方法,并没有做太多。 TextViewApaterMain尝试禁用网格中的所有TextView,除了单击的那个。在OnClick我单击TextView并想要禁用所有其他TextView,因此我调用notifyDataSetChanged,但未调用覆盖areAllItemsEnabledisEnabled(调试器不会停止在断点处)。有任何想法吗?这是一些代码:

public class TextViewAdapterMain extends TextViewAdapter  {

private ArrayList<Boolean> textViewStates = new ArrayList<Boolean>();

public TextViewAdapterMain(Context c) {
    super(c);


    // TODO Auto-generated constructor stub
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return DbManager.getInstance(mContext).getCategoryCount(true);
}

@Override
protected void setCategoryView(View view, int index) {
    // TODO Auto-generated method stub      

    TextView textView = (TextView)view.findViewById(R.id.timer_textview);       
    textView.setGravity(Gravity.CENTER);
    textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 40));

    CheckBox checkbox = (CheckBox)view.findViewById(R.id.timer_checkbox);
    checkbox.setVisibility(View.GONE);
}   

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

    ((TimeManagerActivity)super.mContext).launchChronometer((TextView)arg0);


    this.notifyDataSetChanged();
}

@Override
protected Category getCategory(int index) {
    // TODO Auto-generated method stub
    return DbManager.getInstance(this.mContext).getCategoryByIndex(index, true);
}

@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position)
{                           
    if(textViewStates.get(position))
        return true;

    return false;

}

}

1 个答案:

答案 0 :(得分:0)

这可能行不通。您需要做的是覆盖BaseAdapter类中的两个函数,如下所示:

@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position) {
    if(isEnabledData[pos])
        return true;

    return false;
}

这也意味着您需要为数据/模型添加一种方法来跟踪选择状态,在我的示例中,我使用带有true或false的简单boolean []。 BaseAdapter在将网格项绘制到屏幕时将使用isEnabled。

如果您需要更改项目的状态,请更改为模型数据isEnable [x] = true / false,然后在适配器上调用notifyDatasetChanged()。