自定义布局不适用于列表视图(单选)
Custom layout not working with List view (Single choice)
我尝试使用单选列表视图设计自定义布局,但选择模式不起作用。下面是相关代码。
public class CheckableFrameLayout extends FrameLayout implements Checkable {
private boolean isChecked;
public CheckableFrameLayout(Context context) {
super(context);
}
public CheckableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CheckableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CheckableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setChecked(boolean b) {
setEnabled(b);
isChecked = b;
traverseAndCheck(this, b);
}
private void traverseAndCheck(View v, boolean b){
if(v instanceof ViewGroup){
int count = ((ViewGroup)v).getChildCount();
for(int i = 0; i< count; i++){
View c = ((ViewGroup)v).getChildAt(i);
if(c instanceof Checkable){
((Checkable)c).setChecked(b);
}
else if (c instanceof ViewGroup) {
traverseAndCheck(c, b);
}
}
}
refreshDrawableState();
}
@Override
public boolean isChecked() {
return isChecked;
}
@Override
public void toggle() {
isChecked = !isChecked;
setEnabled(isChecked);
traverseAndToggle(this);
}
private void traverseAndToggle(View v) {
if (v instanceof ViewGroup) {
int count = ((ViewGroup)v).getChildCount();
for (int i = 0; i < count; i++) {
View c = ((ViewGroup)v).getChildAt(i);
if (c instanceof Checkable) {
((Checkable)c).toggle();
}
else if(c instanceof ViewGroup) {
traverseAndToggle(c);
}
}
}
refreshDrawableState();
}
}
这是商品。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="userCard"
type="com.innofied.saferyde.model.UserCard"/>
</data>
<com.innofied.saferyde.widget.CheckableFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="10dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/cardview_dark_background"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/payment_check_drawable"
android:button="@null"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
<ImageView
android:id="@+id/card_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/check"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_toRightOf="@+id/card_type"
android:layout_toLeftOf="@+id/exp_date_txt">
<TextView
android:id="@+id/name_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:textAllCaps="true"
android:text="@{userCard.name}"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/card_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:text='@{"**** **** **** " + userCard.last4}'
/>
</LinearLayout>
<TextView
android:id="@+id/exp_date_txt"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:text='@{"Exp.\n" + userCard.exp_month + "/" + userCard.exp_year }'/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</com.innofied.saferyde.widget.CheckableFrameLayout>
</layout>
如果需要,我可以粘贴适配器代码。
我已经在列表视图上设置了singleChoiceMode,我还需要做什么?
当我单击列表项时,未调用 CheckableFrameLayout 的 setChecked() 方法。
技巧是使用 CheckedTextView 代替 Checkbox。我还没有缩小到原因。所以我只是改变了部分
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/payment_check_drawable"
android:button="@null"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
到
<CheckedTextView
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:checkMark="@drawable/payment_check_drawable"
android:gravity="left"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
查看测试代码here
我尝试使用单选列表视图设计自定义布局,但选择模式不起作用。下面是相关代码。
public class CheckableFrameLayout extends FrameLayout implements Checkable {
private boolean isChecked;
public CheckableFrameLayout(Context context) {
super(context);
}
public CheckableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CheckableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CheckableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setChecked(boolean b) {
setEnabled(b);
isChecked = b;
traverseAndCheck(this, b);
}
private void traverseAndCheck(View v, boolean b){
if(v instanceof ViewGroup){
int count = ((ViewGroup)v).getChildCount();
for(int i = 0; i< count; i++){
View c = ((ViewGroup)v).getChildAt(i);
if(c instanceof Checkable){
((Checkable)c).setChecked(b);
}
else if (c instanceof ViewGroup) {
traverseAndCheck(c, b);
}
}
}
refreshDrawableState();
}
@Override
public boolean isChecked() {
return isChecked;
}
@Override
public void toggle() {
isChecked = !isChecked;
setEnabled(isChecked);
traverseAndToggle(this);
}
private void traverseAndToggle(View v) {
if (v instanceof ViewGroup) {
int count = ((ViewGroup)v).getChildCount();
for (int i = 0; i < count; i++) {
View c = ((ViewGroup)v).getChildAt(i);
if (c instanceof Checkable) {
((Checkable)c).toggle();
}
else if(c instanceof ViewGroup) {
traverseAndToggle(c);
}
}
}
refreshDrawableState();
}
}
这是商品。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="userCard"
type="com.innofied.saferyde.model.UserCard"/>
</data>
<com.innofied.saferyde.widget.CheckableFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="10dp">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@color/cardview_dark_background"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/payment_check_drawable"
android:button="@null"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
<ImageView
android:id="@+id/card_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/check"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_toRightOf="@+id/card_type"
android:layout_toLeftOf="@+id/exp_date_txt">
<TextView
android:id="@+id/name_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:textAllCaps="true"
android:text="@{userCard.name}"
android:layout_marginBottom="5dp"/>
<TextView
android:id="@+id/card_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:text='@{"**** **** **** " + userCard.last4}'
/>
</LinearLayout>
<TextView
android:id="@+id/exp_date_txt"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorWhite"
android:text='@{"Exp.\n" + userCard.exp_month + "/" + userCard.exp_year }'/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</com.innofied.saferyde.widget.CheckableFrameLayout>
</layout>
如果需要,我可以粘贴适配器代码。
我已经在列表视图上设置了singleChoiceMode,我还需要做什么? 当我单击列表项时,未调用 CheckableFrameLayout 的 setChecked() 方法。
技巧是使用 CheckedTextView 代替 Checkbox。我还没有缩小到原因。所以我只是改变了部分
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/payment_check_drawable"
android:button="@null"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
到
<CheckedTextView
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:checkMark="@drawable/payment_check_drawable"
android:gravity="left"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
/>
查看测试代码here