左側のフラグメントに展開可能なリストがあり、右側の詳細フラグメントがあるレイアウトがあります。これはすべて正常に動作します。
ここで、左側のどのアイテムが右側に詳細が表示されているのかを示したいのですが、ここで問題が発生しています。
通常のリストビューでは、リストビューの選択モードをシングルに設定し、「アクティブ化」状態に基づいてドローアブル状態を使用することで、これを実現しています。アイテムをクリックすると、背景は選択した色に設定され、リスト上の別のアイテムを選択するまでそのままになります。
これを拡張可能なリストビューに適用しようとしましたが、これは悲惨な失敗でした。エラーはありませんでしたが、選択したアイテムは色の状態を維持していませんでした。選択モードを適切に設定していないかどうか(レイアウトファイルでもプログラムで試してみましたが、違いはないようです)、または間違っていることを指しているかどうかわかりません(それがどのようになるかはわかりませんが...)
どんなヘルプ/ポインタも感謝します(それが完全に異なる方向であっても)。
現在の失敗:
展開可能なリストビューコード
private void fillData(String group, String child) {
ExpandableListView lv;
mGroupsCursor = mDbHelper.fetchGroup(group);
getActivity().startManagingCursor(mGroupsCursor);
mGroupsCursor.moveToFirst();
lv = (ExpandableListView) getActivity().findViewById(R.id.explist);
lv.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE);
mAdapter = new MyExpandableListAdapter(mGroupsCursor, getActivity(),
R.layout.explistlayout,
R.layout.explistlayout,
new String[] { "_id" },
new int[] { Android.R.id.text1 },
new String[] { child },
new int[] { Android.R.id.text1 });
lv.setAdapter(mAdapter);
registerForContextMenu(lv);
lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
{
mRowId = id;
EventDisplayFragment eventdisplay = new EventDisplayFragment();
getFragmentManager().beginTransaction().replace(R.id.rightpane, eventdisplay).commit();
return true;
}
});
}
public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
public MyExpandableListAdapter(Cursor cursor, Context context,
int groupLayout, int childLayout, String[] groupFrom,
int[] groupTo, String[] childrenFrom, int[] childrenTo) {
super(context, cursor, groupLayout, groupFrom, groupTo,
childLayout, childrenFrom, childrenTo);
}
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
Cursor childCursor = mDbHelper.fetchChildren(mGroup, groupCursor
.getString(groupCursor
.getColumnIndex(AttendanceDB.EVENT_ROWID)));
getActivity().startManagingCursor(childCursor);
childCursor.moveToFirst();
return childCursor;
}
}
item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:state_pressed="true"
Android:drawable="@color/green" />
<item
Android:state_selected="true"
Android:drawable="@color/blue" />
<item
Android:state_focused="true"
Android:drawable="@color/Violet" />
<item
Android:state_activated="true"
Android:drawable="@color/blue" />
</selector>
ExpandableListViewで以下を実行します。
ステップ1。選択モードを単一に設定します(xmlでAndroid:choiceMode = "singleChoice"として実行できます)
ステップ2。セレクターxmlを背景として使用(Android:listSelector = "@ drawable/selector_list_item")
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:exitFadeDuration="@Android:integer/config_mediumAnimTime">
<item Android:drawable="@Android:color/holo_blue_bright" Android:state_pressed="true"/>
<item Android:drawable="@Android:color/holo_blue_light" Android:state_selected="true"/>
<item Android:drawable="@Android:color/holo_blue_dark" Android:state_activated="true"/>
</selector>
手順3。呼び出しexpandableListView.setItemChecked(index、true) onChildClick()コールバック。
indexは、次のように計算された子アイテムの0ベースのインデックスです
グループ1 [インデックス= 0]
グループ2 [インデックス= 4]
グループ [インデックス= 8]
リストヘッダーもある場合、それらはインデックス値も考慮します。
これが実際の例です:
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
...
int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
parent.setItemChecked(index, true);
return true;
}
3〜4時間を費やした後、追加のXMLファイルを作成する必要はないので、グループアイテムが展開されているかどうかを確認します。展開されている場合は色を選択し、elseステートメントでそのままにします。
@Override
//in this method you must set the text to see the parent/group on the list
public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.list_item_parent, viewGroup,false);
}
if(b){
view.setBackgroundResource(R.color.waterblue);
}else{
view.setBackgroundColor(color.transparent);
}
//return the entire view
return view;
}
私はようやくこれを機能させる方法を見つけました(私にとって)。少しハックのように見えますが、これが私がこれのためにうまくやった唯一のものです。
基本的に、子の選択状態を保持する2次元配列を作成し、それをアダプターコンストラクターで初期化してから、それをgetChildView
メソッドで参照します(現在選択されている子がスクロールして表示されない場合)。 onChildClick
メソッド(現在の選択を変更し、古い選択をオフにするため)。
private selectedStatus[][]; // array to hold selected state
private View oldView; // view to hold so we can set background back to normal after selection of another view
コンストラクタ配列を初期化します
public MyExpandableListAdapter(Cursor cursor, Context context,
int groupLayout, int childLayout, String[] groupFrom,
int[] groupTo, String[] childrenFrom, int[] childrenTo) {
super(context, cursor, groupLayout, groupFrom, groupTo,
childLayout, childrenFrom, childrenTo);
selectedStatus = new boolean[cursor.getCount()][];
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToPosition(i);
Cursor childCheckCursor = mDbHelper.fetchChildren(mGroup,
cursor.getString(cursor
.getColumnIndex(AttendanceDB.EVENT_ROWID)));
getActivity().startManagingCursor(childCheckCursor);
selectedStatus[i] = new boolean[childCheckCursor.getCount()];
for (int j = 0; j < childCheckCursor.getCount(); j++) {
selectedStatus[i][j] = false;
}
}
}
getChildView子がビューの外にスクロールしたときに必要
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final View v = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
if(selectedStatus[groupPosition][childPosition] == true){
v.setBackgroundResource(R.color.blue);
} else {
v.setBackgroundResource(R.color.black);
}
return v;
}
onChildClick選択したアイテムを変更
lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
mRowId = id;
EventDisplayFragment eventdisplay = new EventDisplayFragment();
getFragmentManager().beginTransaction()
.replace(R.id.rightpane, eventdisplay).commit();
if(oldView != null){
oldView.setBackgroundResource(R.color.black); // change the background of the old selected item back to default black }
oldView = v; // set oldView to current view so we have a reference to change back on next selection
for (int i = 0; i < selectedStatus.length; i++) {
for (int j = 0; j < checkedStatus[i].length; j++) {
if(i == groupPosition && j == childPosition){ // set the current view to true and all others to false
selectedStatus[i][j] = true;
} else {
selectedStatus[i][j] = false;
}
}
}
v.setBackgroundResource(R.color.blue);
return true;
}
});
onchildclick
メソッドよりも子アイテムの色だけを変更する必要がある場合は、背景色をビューvに設定します。
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
v.setBackgroundColor(Color.RED);
}
そのためには、アダプターでisChildSelectable
をtrueに設定します。
次のソリューションは、グループと子に異なるリストセレクターを作成するのに役立ちます。
まず、ExpendableListViewのリストセレクターを無効にする必要があります。
...
<ExpandableListView
...
Android:listSelector="@Android:color/transparent"
...
/>
...
その後、空のlistSelectorをコピーする必要があります。このようにできます
...
private Drawable empty;
...
// binding view here. Name of ExpandableListView will be elv
empty = elv.getSelector();
ここで、リストセレクターを有効にするか無効にするかを知る必要があります。そのため、次の変更をアダプターに追加する必要があります。
my adapter here {
...
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent)
{
...
// after, we've got view of goup
view.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
elv.setSelector(empty);
return false;
}
});
...
}
...
@Override
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent)
{
...
// after, we've got view of child
view.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
elv.setSelector(R.drawable.my_custom_list_selector);
return false;
}
});
...
}
...
}
それで全部です。この解決策があなたの時間を守ってくれることを願っています。
私はこれを修正して同じ問題を抱えていました
v.setSelected(true);
これが私のコードのサンプルです:
expandableListDetailsLevel.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE);
expandableListDetailsLevel
.setOnGroupExpandListener(new OnGroupExpandListener() {
public void onGroupExpand(int groupPosition) {
if(groupPosition!=1){
expandableIsThere = false;
}
for (int i = 0; i < len; i++) {
if (i != groupPosition) {
expandableListDetailsLevel.collapseGroup(i);
}
}
}
});
expandableListDetailsLevel
.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent,
View v, int groupPosition, int childPosition,
long id) {
v.setSelected(true);
}
私のアイテムのxml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal"
Android:background="@drawable/selector" >
<TextView
Android:id="@+id/TVChild"
Android:layout_width="fill_parent"
Android:layout_height="match_parent"
Android:textColor="#000"
Android:textSize="12dp"/>
</LinearLayout>
属性Android:drawSelectorOnTop="true"
次のように、xmlファイルのExpandableListView要素(アイテムの子やグループではなく)で:
<ExpandableListView
Android:id="@+id/expandableViewDetailsBriefing"
Android:layout_width="fill_parent"
Android:layout_height="match_parent"
Android:background="#fff"
Android:drawSelectorOnTop="true"
Android:dividerHeight="1px"
Android:childDivider="@color/Gris"
Android:indicatorRight="690dp"
Android:textFilterEnabled="true" >
</ExpandableListView>
この簡単な解決策は、著者と同じ質問に直面したときに役立ちました
左側のフラグメントに展開可能なリストがあり、右側の詳細フラグメントがあるレイアウトがあります。これはすべて正常に動作します。次に、左側のどのアイテムが右側に詳細が表示されているのかを示しますが、ここで問題が発生しています。
展開可能なリストのどの項目が選択されているかを示すには、(レイアウトの)ExpandableListViewプロパティに移動し、listSelectorの色を選択します。
現在のビューを保存して、クリックリスナー内のビューの背景色を変更できます。
View currentView;
ExpandableListView elv;
elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
if(currentView != null) {
currentView.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
v.setBackgroundColor(Color.parseColor("#EEEEEE"));
currentDrawerView = view;
//do something
return false;
}
});
elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
if(currentView != null) {
currentView.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
v.setBackgroundColor(Color.parseColor("#EEEEEE"));
currentDrawerView = view;
//do something
return false;
}
});
expListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick( ExpandableListView parent, View v,
int groupPosition, int childPosition,
long id) {
for (int i = 1; i < expListView.getChildCount(); i++) {
View child = (View) expListView.getChildAt(i);
child.setBackgroundColor(Color.BLACK);
}
if(childPosition==0){
initWebView("URL");
}
if(childPosition==1) {
initWebView("URL");
}
if(childPosition==2) {
initWebView("URL");
}
if(childPosition==3) {
initWebView("URL");
}
if(childPosition==4) {
initWebView("URL");
}
if(childPosition==5) {
initWebView("URL");
}
v.setBackgroundColor(Color.GRAY);
expListView.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
return false;
}
});
}
expListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick( ExpandableListView parent, View v,
int groupPosition, int childPosition,
long id) {
for (int i = 1; i < expListView.getChildCount(); i++) {
View child = (View) expListView.getChildAt(i);
child.setBackgroundColor(Color.BLACK);
}
if(childPosition==0){
initWebView("URL");
}
if(childPosition==1) {
initWebView("URL");
}
if(childPosition==2) {
initWebView("URL");
}
if(childPosition==3) {
initWebView("URL");
}
if(childPosition==4) {
initWebView("URL");
}
if(childPosition==5) {
initWebView("URL");
}
v.setBackgroundColor(Color.GRAY);
expListView.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
return false;
}
});
}