2012-04-25 5 views
0

問題: リストビューをクリアして再投入すると、アイテムが以前にチェックされていた場合、同じインデックスのアイテムもチェックされます。アダプタに追加された要素の数が前にチェックされた項目のインデックスである場合、何もチェックされません。Android Checkable ListViewアイテムがチェックされたままになる

convertViewの使用をブロックしようとしましたが、存在しても効果がありません。不思議なことに、私がデバッガを踏んで何が起こっているのかを確認すると、アダプタを再投入するとCheckableLinearLayoutのsetChecked(true)への呼び出しが1回以上発生します。 (私は以下のスタックトレースを含んでいます)。これらの呼び出しのコールスタックを見ると、これらの呼び出しを起源とするコードはありません。それは、ListViewが以前の選択のインデックスを覚えていて、それをそれ自身のものに復元しているかのようです。

私の実装: 私はリストビューをsingleSelectionモードに設定しました。

public class CheckableLinearLayout extends LinearLayout implements Checkable { 

    private boolean isChecked; 

    public CheckableLinearLayout(Context context) { 
     super(context); 
    } 

    public CheckableLinearLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void setChecked(boolean isChecked) { 
     this.isChecked = isChecked; 
     if(isChecked) { 
     setBackgroundColor(Color.DKGRAY); 
     } else { 
     setBackgroundColor(Color.BLACK); 
     } 
    } 

    @Override 
    public boolean isChecked() { 
     return isChecked; 
    } 

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

マイArrayAdapterのgetViewメソッドの実装:

@Override 
public View getView(int pos, View convertView, ViewGroup parent) { 

     LayoutInflater inf = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     CheckableLinearLayout row = (CheckableLinearLayout) convertView; 
     if (row == null) { 
      row = (CheckableLinearLayout) inf.inflate(R.layout.file_explorer_item, parent, false); 
     } 

     // I explicitly set checked to false, in case this was a convertView: 
     row.setChecked(false); 

     // population various elements of the view is done here 

     return row; 
     } 
    } 

任意のアイデア私は私のCheckableListView実装のインスタンスを返しますgetViewメソッド(...)を持つカスタムArrayAdapterを使うのか?

PS。ここでは謎の一つのスタックトレースがsetChecked(真)の呼び出しです:

<1> [email protected], prio=5, in group 'main', status: 'RUNNING' 
     at my.package.CheckableLinearLayout.setChecked(CheckableLinearLayout.java:25) 
     at android.widget.ListView.setupChild(ListView.java:1834) 
     at android.widget.ListView.makeAndAddView(ListView.java:1765) 
     at android.widget.ListView.fillSpecific(ListView.java:1318) 
     at android.widget.ListView.layoutChildren(ListView.java:1636) 
     at android.widget.AbsListView.onLayout(AbsListView.java:1863) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1617) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1401) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:431) 
     at android.view.View.layout(View.java:11278) 
     at android.view.ViewGroup.layout(ViewGroup.java:4224) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1489) 
     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) 
     at android.os.Handler.dispatchMessage(Handler.java:99) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:4424) 
     at java.lang.reflect.Method.invokeNative(Method.java:-1) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
     at dalvik.system.NativeStart.main(NativeStart.java:-1) 

<10> Binder Thread #[email protected], prio=5, in group 'main', status: 'RUNNING' 
     at dalvik.system.NativeStart.run(NativeStart.java:-1) 

<9> Binder Thread #[email protected], prio=5, in group 'main', status: 'RUNNING' 
     at dalvik.system.NativeStart.run(NativeStart.java:-1) 

<8> [email protected] daemon, prio=5, in group 'main', status: 'SLEEPING' 
     at java.lang.VMThread.sleep(VMThread.java:-1) 
     at java.lang.Thread.sleep(Thread.java:1031) 
     at java.lang.Thread.sleep(Thread.java:1013) 
     at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:213) 
     at java.lang.Thread.run(Thread.java:856) 

<7> [email protected] daemon, prio=5, in group 'main', status: 'WAIT' 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.Object.wait(Object.java:401) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:102) 
     at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:73) 
     at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168) 
     at java.lang.Thread.run(Thread.java:856) 

<6> [email protected] daemon, prio=5, in group 'main', status: 'WAIT' 
     at java.lang.Object.wait(Object.java:-1) 
     at java.lang.Object.wait(Object.java:364) 
     at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:128) 
     at java.lang.Thread.run(Thread.java:856) 

<5> [email protected] daemon, prio=5, in group 'system', status: 'WAIT' 
     at dalvik.system.NativeStart.run(NativeStart.java:-1) 

<3> Signal [email protected] daemon, prio=5, in group 'system', status: 'WAIT' 
     at dalvik.system.NativeStart.run(NativeStart.java:-1) 

<2> [email protected] daemon, prio=5, in group 'system', status: 'WAIT' 
     at dalvik.system.NativeStart.run(NativeStart.java:-1) 
+1

Afaik setCheckedが呼び出されますgetViewの後にgetCheckedItemPosition(ListView setItemCheckedで設定)からの値を持つListViewの値を取得します。おそらく、内部のコンテナは、アダプタがクリアまたは変更されたときにクリアされません。必要に応じて項目のチェックを外します。 – Deucalion

+0

'ListView'で' setChoiceMode(ListView.CHOICE_MODE_SINGLE); 'を呼びますか? 私の経験では、CHOICE_SINGLE_MODEのListViewはこのような問題を単独で処理します。 – Longerian

+0

@Longerian:Nope - 私はListViewに適用されるXMLスタイルでそれを行います。 <スタイル名= "MyListViewを"> <=項目名 "アンドロイド:choiceMode"> singleChoice <項目名= "アンドロイド:パディング"> 8DP 私が知っているスタイルは、このようなルックスを適用しましたXMLを介して設定したときに無視されるこの設定のレポートがありましたが、クイックテストでは、コメントアウトすると単一の選択モードが有効にならず、アイテムがクリックされたときにチェックされませんでした。 – Nick

答えて

0

はgetViewメソッド後(リストビューsetItemCheckedで設定)getCheckedItemPosition(S)の値とリストビューによって呼び出されるであろう。おそらく、内部のコンテナは、アダプタがクリアまたは変更されたときにクリアされません。必要に応じて項目のチェックを外します。

私は、状態リストドロウブルを使用することをお勧めします。 onCreateDrawableState、mergeDrawableState、refreshDrawableState、state_checkedです。ちょうどGoogle。;それがクリックのステータスだ変えるので -

0

あなたがリストビューにアイテムを移動するたびに、それはその各行を再作成ができますが、その状態を保存していないとして、これはありますレクリエーションでは、状態を削除してデフォルト状態に設定します。私はすでにあなたがそれが有用であることを確認することができるということに関連する回答を掲示している。 (チェック可能インタフェースがある場合)

setChecked

How to implement a button that gets all checkbox's state and adds the value of checked item into arraylist?

+0

私の問題は実際には逆です:リストビューを再作成すると状態を保持したくありません。さらに、isCheckedのデフォルト状態はfalse(デフォルトはboolean)で、その上にリバース・ビューが使用されている場合は、getView()を明示的にfalseに設定します。 – Nick

+0

あなたの状態を保存したり保存したりしたくない場合は、それを保存する必要はありません。 –

+0

私はそれに応じて設定していると言おうとしていますが、私が設定しているものを上書きするものがあります。私が知らないものではあるが、デバッガはsetChecked(true)が呼び出されていることを示している。 – Nick

5

あなたは

performClickが上書きされ、このCheckableLinearLayout

public class CheckableLinearLayout extends LinearLayout implements Checkable { 
boolean mChecked = false; 

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

public CheckableLinearLayout(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

@Override 
public boolean isChecked() { 
    return mChecked; 
} 

@Override 
public void setChecked(boolean checked) { 
    if (mChecked != checked) { 
     mChecked = checked; 
     refreshDrawableState(); 
    } 
} 

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

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

@Override 
public boolean performClick() { 
    toggle(); 
    return super.performClick(); 
} 

}を使用することができますここで

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="true"> 
     <shape android:shape="rectangle"> 
      <solid android:color="#e13f2e"/> 
     </shape> 
    </item> 
    <item android:state_checked="false"> 
     <shape android:shape="rectangle"> 
      <solid android:color="#ffffff"/> 
     </shape> 
    </item> 
</selector> 
+0

エラーが発生しました: 'state_checkedは解決できないか、フィールドではありません。 ' –

+0

@ LuisA.Florit try android.R.attr.state_checked – Paul

0

CheckableRelativeLayoutの良い実装です:あなたはこのようなものを使用することができ、背景色のためにそれを

を必要としない場合はそれを削除link

また、リストビューSINGLE_CHOICEを設定する(または複数の)レイアウト/ xmlで動作しませんでしたが、アダプタの設定後にこれを代わりに使用しました

​​3210
関連する問題