2012-08-02 26 views
4

我嘗試使用RelativeLayoutTextViewFrameLayout(在選擇器背景)內寫我自己的CheckBox使RelativeLayout可檢查

我有setDuplicateParentStateEnabled(true)對於FrameLayout它從父級檢查狀態,但爲什麼使RelativeLayout檢查我不知道。

public class MyCheckbox extends RelativeLayout implements OnClickListener, Checkable 
{ 
private static final int ID_CHECKBOX = -1234411; 
private static final int ID_TEXTVIEW = -1234412; 
private static final int ID_PARENT = -1234413; 

private TextView textView; 
private FrameLayout checkBox; 
private boolean isChecked; 

public MyCheckbox(Context context) 
{ 
    this(context, null); 
} 

public MyCheckbox(Context context, AttributeSet attrs) 
{ 
    super(context, attrs); 

    LayoutParams lp; 

    setId(ID_PARENT); 
    setOnClickListener(this); 

    // checkBox 
    checkBox = new FrameLayout(context); 
    checkBox.setId(ID_CHECKBOX); 
    checkBox.setDuplicateParentStateEnabled(true); 

    // textView 
    textView = new TextView(context); 
    textView.setId(ID_TEXTVIEW); 
    textView.setOnClickListener(this); 


    boolean checkboxToRight = false; 

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MaptrixCheckbox); 

    for (int i = 0; i < a.getIndexCount(); i++) 
    { 
     int attr = a.getIndex(i); 
     switch (attr) 
     { 
      case R.styleable.MyCheckbox_checkboxToRight: 
       checkboxToRight = a.getBoolean(attr, false); 
       break; 

      case R.styleable.MyCheckbox_checkMark: 
       checkBox.setBackgroundDrawable(a.getDrawable(attr)); 
       break; 

      case R.styleable.MyCheckbox_text: 
       textView.setText(a.getText(attr)); 
       break; 
     } 
    } 
    a.recycle(); 

    if (checkboxToRight) 
    { 
     lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
     lp.addRule(ALIGN_PARENT_RIGHT); 
     lp.addRule(CENTER_VERTICAL); 
     lp.setMargins(margins, 0, margins, 0); 
     addView(checkBox, lp); 

     lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
     lp.addRule(CENTER_VERTICAL); 
     lp.addRule(LEFT_OF, ID_CHECKBOX); 
     addView(textView, lp); 
    } 
    else 
    { 
     lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
     lp.addRule(CENTER_VERTICAL); 
     lp.setMargins(margins, 0, margins, 0); 
     addView(checkBox, lp); 

     lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 
     lp.addRule(CENTER_VERTICAL); 
     lp.addRule(RIGHT_OF, ID_CHECKBOX); 
     addView(textView, lp); 
    } 

    refreshDrawableState(); 
} 

@Override 
public void onClick(View v) 
{ 
    int id = v.getId(); 

    if (id == ID_PARENT || id == ID_TEXTVIEW) toggle(); 
} 

public boolean isChecked() 
{ 
    return isChecked; 
} 

public void setChecked(boolean chacked) 
{ 
    isChecked = chacked; 
    refreshDrawableState(); 
} 

@Override 
public void toggle() 
{ 
    isChecked = !isChecked; 
    refreshDrawableState(); 
} 
} 

回答

5

我只需要重寫方法:

private static final int[] STATE_CHECKABLE = {android.R.attr.state_checked}; 

@Override 
protected int[] onCreateDrawableState(int extraSpace) 
{ 
    int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
    if (isChecked) mergeDrawableStates(drawableState, STATE_CHECKABLE); 
    return drawableState; 
} 

現在所有的作品。

+1

試了一下。 。?對4.0.3 X-不起作用( – Mus 2012-11-06 11:22:30

+0

畝,我的應用程序在4.0.3和4.1.1的精品工程,此代碼 – Nik 2012-11-06 11:27:41

+0

您可以發佈您的佈局XML,我有太多的問題你有沒有設置機器人:點擊在萬一佈局=「真」? – 2014-04-15 12:13:12

8

似乎有對在全息多選列表(在ActionMode的上下文中)兩個UI模式:使用複選框或高亮。

如果你需要的是突出,你可以用這個簡單的方法:

使根列表項的佈局使用的一類像這樣的:

public class CheckableRelativeLayout extends RelativeLayout implements Checkable { 
private static final int[] STATE_CHECKABLE = {R.attr.state_pressed}; 
boolean checked = false; 

public void setChecked(boolean checked) { 
    this.checked = checked; 
    refreshDrawableState(); 
} 

public boolean isChecked() { 
    return checked; 
} 

public void toggle() { 
    setChecked(!checked); 
} 

@Override 
protected int[] onCreateDrawableState(int extraSpace) { 
    int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 
    if (checked) mergeDrawableStates(drawableState, STATE_CHECKABLE); 

    return drawableState; 
} 
} 

,並確保根元素在您的列表項目佈局使用

android:background="?android:attr/listChoiceBackgroundIndicator" 

我知道這是不是一個真正的回答你的問題(你想要一個實際的複選框),但我還沒有看到這個記錄anywhe回覆。

ListView控件使用勾選的接口,以確定它是否可以依靠列表項元素上顯示可檢查狀態,還是應儘量顯示它本身。

+0

非常感謝你爲這個@皮埃爾 - 呂克!我在浪費了太多時間在這過去幾天和你的實現是一個很好的起點,我也不想一個複選框,但實現可檢驗的需要 – krider2010 2013-12-07 21:15:47

+0

@皮埃爾 - 呂克,你是一個傳奇先生,我是繼[本教程(HTTP:。。/ /www.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/)來實現可檢查的RelativeLayout但缺少refreshDrawableState()。我的ListView項目不得不被觸摸兩次成爲該選項之前(突出顯示)。 – 2014-01-03 12:36:29

+0

當然是sup構成「R.attr.state_pressed」? – 2015-11-08 11:08:51

3

Nik的回答對我來說是部分正確的,你需要將STANDARD_CHECKABLE數組中添加android.R.attr.state_checkable,並設置相應的lenth(2),否則失敗。

private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked, android.R.attr.state_checkable}; 

@Override 
protected int[] onCreateDrawableState(int extraSpace) 
{ 
    int[] result = super.onCreateDrawableState(extraSpace + CHECKED_STATE_SET.length); 
    if(mChecked) mergeDrawableStates(result, CHECKED_STATE_SET); 
    return result; 
}