我有一个列表(ExpandableListView),列表中的每个项目都有一个ToggleButton,它在切换时显示/隐藏子项(子项始终为1,它是一种带有两个按钮的工具栏)。感谢this教程,我可以设置一个自定义按钮而不是expandablelistview的指示器,我这样做是为了除了在单击列表项目时显示工具栏,我还可以做其他事情。此外,我使用this question的答案在打开另一个时自动关闭打开的工具栏。 因此,当触摸屏幕上不是ToggleButton的任何内容时,我需要折叠当前展开的工具栏(即使单击工具栏的某个按钮,我也需要折叠它,只要它自己的“onClick”仍然发送)
这是应用程序的图像:
这是ExpandableListView:
<ExpandableListView
android:id="@+id/normalList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:groupIndicator="@drawable/toggle_button_selector" >
</ExpandableListView>
这是组项的xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/filesListDrawerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp" >
<ImageView
android:id="@+id/img"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="2dp"
android:contentDescription="@string/icondescription" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:layout_alignTop="@+id/img"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/img"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_alignBottom="@+id/img"
android:layout_below="@+id/text"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/img"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ToggleButton
android:id="@+id/toggle"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentRight="true"
android:layout_below="@+id/text"
android:layout_marginRight="15dp"
android:background="@drawable/toggle_button_selector"
android:focusable="false"
android:focusableInTouchMode="false"
android:textColorLink="@android:color/transparent"
android:textOff=""
android:textOn="" />
子项:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/details"
android:layout_width="0dp"
android:layout_height="57dip"
android:layout_weight="1"
android:clickable="true"
android:drawableTop="@drawable/ic_action_about"
android:drawablePadding="-12dp"
android:background="@drawable/toolbar_selector"
android:gravity="center"
android:text="@string/details" />
<TextView
android:id="@+id/send"
android:layout_width="0dp"
android:layout_height="57dip"
android:layout_weight="1"
android:clickable="true"
android:drawableTop="@drawable/ic_action_new_email"
android:drawablePadding="-12dp"
android:background="@drawable/toolbar_selector"
android:gravity="center"
android:text="@string/send" />
</LinearLayout>
适配器的相关部分:
public class CustomList extends BaseExpandableListAdapter {
private final Activity context;
public final List<Item> names; //Item is a custom Object
private final Integer[] imageId;
private int lastExpandedGroupPosition;
public CustomList(Activity context, List<Item> names, Integer[] imageId) {
this.context = context;
this.names = names;
this.imageId = imageId;
}
public View getGroupView(final int position, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_single, null);
}
TextView txtTitle = (TextView) convertView.findViewById(R.id.text);
TextView txtData = (TextView) convertView.findViewById(R.id.counter);
ImageView imageView = (ImageView) convertView.findViewById(R.id.img);
ToggleButton toggle = (ToggleButton) convertView.findViewById(R.id.toggle);
final ExpandableListView list = (ExpandableListView) parent.findViewById(R.id.normalList);
txtTitle.setText(names.get(position).getName());
txtData.setText(names.get(position).getData());
if(/*some conditions*/) {
imageView.setImageResource(imageId[0]);
toggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
list.expandGroup(position, true);
} else {
list.collapseGroup(position);
}
}
});
} else if(/*other conditions*/) {
imageView.setImageResource(imageId[2]);
toggle.setVisibility(View.GONE);
} else {
imageView.setImageResource(imageId[1]);
toggle.setVisibility(View.GONE);
}
return convertView;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_child, null);
}
TextView details = (TextView) convertView.findViewById(R.id.details);
TextView send = (TextView) convertView.findViewById(R.id.send);
details.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//do something
}
});
send.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//do something else
}
});
return convertView;
}
@Override
public void onGroupExpanded(int groupPosition) {
ToggleButton button = (ToggleButton) ((ExpandableListView) context
.findViewById(R.id.normalList)).getChildAt(lastExpandedGroupPosition)
.findViewById(R.id.toggle);
if(groupPosition != lastExpandedGroupPosition && button.isChecked()) {
button.performClick();
}
super.onGroupExpanded(groupPosition);
lastExpandedGroupPosition = groupPosition;
}
}
最后活动中的重要部分:
lv = (ExpandableListView)findViewById(R.id.normalList);
lv.setGroupIndicator(null);
lv.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int position, long id) {
//do some things
return true; //this tells the list that it mustn't show the child items
}
});
adapter = new CustomList(myActivity.this, list, icons);
lv.setAdapter(adapter);
P.S。:隐藏打开的工具栏的代码无法正常工作,但我真的无法理解为什么。但这是另一个故事......
---编辑---
关于P.S.上图:now I know why that happens。
答案 0 :(得分:1)
您的列表看起来像ExpandableListView。你试过用它吗?它构建了第二级行,扩展,隐藏等。只需将您的pdf行添加为组头,然后将工具行添加为子行。然后,您可以处理行单击以显示和隐藏要显示/隐藏的行。请参阅:http://developer.android.com/reference/android/widget/ExpandableListView.html
而且,顺便说一下,使用隐藏的其他行有点错误的用户体验设计。也许最好使用下拉列表或自定义对话框窗口?它们都具有内置功能,在外面触摸时会消失。
答案 1 :(得分:0)
在ArrayList中填充列表时,您可以简单地放置所有ToggleButton。这样,只需单击其中一个按钮,就可以强制单击列表中的每个按钮。
答案 2 :(得分:0)
好的,我解决了这个问题 我没有在某些方法中使用“performClick()”或“setChecked”切换按钮并管理OnCheckedChangedListener中的展开/折叠操作,而是决定将togglebuttons的状态存储在数组中,并展开/折叠子视图在“getGroupView”方法中,取决于groupview按钮的状态,其在数组中的位置对应于groupview在列表中的位置。要更新列表,我在适配器上调用notifyDataSetChanged()。 我在ToggleButton周围添加了一个FrameLayout来增加其可点击区域。
这是为清晰起见的代码:
MainActivity的相关部分:
public class MainActivity extends ActionBarActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
.
.
.
ExpandableListView lv = (ExpandableListView) findViewById(R.id.normalList);
CustomList adapter = new CustomList(MainActivity.this, list /*the list of Items, declared elsewhere*/, lv);
lv.setAdapter(adapter);
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.filesListDrawerLayout);
lv.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int position, long id) {
uncheckButtons(mDrawerLayout);
//do some unrelated stuff
return true;
}
});
}
public void uncheckButtons(ViewGroup vg) {
for(int i = 0; i < adapter.buttons.length; ++i)
adapter.buttons[i] = false;
adapter.lastChecked = -1;
adapter.notifyList();
}
适配器的相关部分:
public class CustomList extends BaseExpandableListAdapter {
private final Activity context;
public final List<Item> names; //Item is a custom Object
public boolean[] buttons;
public int lastChecked;
private final Integer[] imageId = new Integer[] { R.drawable.image1, R.drawable.image1, R.drawable.image3 };
private ExpandableListView list;
public CustomList(Activity context, List<Item> names, boolean forUpload, ExpandableListView list) {
this.context = context;
this.names = names;
this.list = list;
this.buttons = new boolean[names.size()];
this.lastChecked = -1;
}
private static class GroupHolder {
TextView txtTitle;
TextView txtData;
ImageView imageView;
ToggleButton toggle;
FrameLayout frame;
}
public View getGroupView(final int position, boolean isExpanded, View convertView, ViewGroup parent) {
GroupHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_single, null);
holder.txtTitle = (TextView) convertView.findViewById(R.id.text);
holder.txtData = (TextView) convertView.findViewById(R.id.counter);
holder.imageView = (ImageView) convertView.findViewById(R.id.img);
holder.toggle = (ToggleButton) convertView.findViewById(R.id.toggle);
holder.frame = (FrameLayout) convertView.findViewById(R.id.frame);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
txtTitle.setText(names.get(position).getName());
txtData.setText(names.get(position).getData());
if(/*some conditions*/) {
imageView.setImageResource(imageId[0]);
holder.frame.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
if(lastChecked != -1) {//if there's a checked button
buttons[lastChecked] = !buttons[lastChecked];//uncheck it
if(position == lastChecked)//if I clicked on the last checked button
lastChecked = -1;//there's no checked button
else {
buttons[position] = !buttons[position];//check the button
lastChecked = position;//and set it as the last checked one
}
notifyList();
}
return false;
}
});
holder.toggle.setChecked(buttons[position]);
if(holder.toggle.isChecked()) {
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2)
list.expandGroup(position);
else
list.expandGroup(position, true);
} else {
list.collapseGroup(position);
}
} else if(/*other conditions*/) {
//do other stuff with the views that don't interest us
}
return convertView;
}
private static class ChildHolder {
TextView details;
TextView send;
TextView other;
}
public View getChildView(final int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ChildHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_child, null);
holder = new ChildHolder();
holder.details = (TextView) convertView.findViewById(R.id.details);
holder.send = (TextView) convertView.findViewById(R.id.send);
holder.other = (TextView) convertView.findViewById(R.id.other);
} else {
holder = (ChildHolder) convertView.getTag();
}
//maybe I could manage the listeners more nicely and without redundance...
holder.details.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point)
lastChecked = -1;//there's no checked button
notifyList();
//call a certain method in the main activity...
}
});
holder.send.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point)
lastChecked = -1;//there's no checked button
notifyList();
//call a certain method in the main activity...
}
});
holder.other.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
buttons[lastChecked] = !buttons[lastChecked];//uncheck the only checked button (it always exists at this point)
lastChecked = -1;//there's no checked button
notifyList();
//call a certain method in the main activity...
}
});
return convertView;
}
public void notifyList() {
this.notifyDataSetChanged();
}
//I don't need OnGroupExpanded anymore
ExpandableListView:
<ExpandableListView
android:id="@+id/normalList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:groupIndicator="@drawable/toggle_button_selector" >
</ExpandableListView>
组项的xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/filesListDrawerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp" >
<ImageView
android:id="@+id/img"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="2dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:contentDescription="@string/icondescription" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="29dp"
android:layout_alignTop="@+id/img"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/img"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/black" />
<TextView
android:id="@+id/counter"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_alignBottom="@+id/img"
android:layout_below="@+id/text"
android:layout_marginLeft="15dp"
android:layout_toRightOf="@+id/img"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/black" />
<FrameLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/text"
android:layout_marginTop="-15dp"
android:clickable="true"
android:paddingTop="10dp"
android:paddingRight="15dp"
android:paddingLeft="10dp" >
<ToggleButton
android:id="@+id/toggle"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="@drawable/toggle_button_selector"
android:clickable="false"
android:duplicateParentState="true"
android:focusable="false"
android:focusableInTouchMode="false"
android:textColorLink="@android:color/transparent"
android:textOff=""
android:textOn="" />
</FrameLayout>
</RelativeLayout>
子项的xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/details"
android:layout_width="0dp"
android:layout_height="57dip"
android:layout_weight="1"
android:clickable="true"
android:drawableTop="@drawable/ic_action_about"
android:drawablePadding="-12dp"
android:background="@drawable/toolbar_selector"
android:gravity="center"
android:text="@string/details" />
<TextView
android:id="@+id/send"
android:layout_width="0dp"
android:layout_height="57dip"
android:layout_weight="1"
android:clickable="true"
android:drawableTop="@drawable/ic_action_new_email"
android:drawablePadding="-12dp"
android:background="@drawable/toolbar_selector"
android:gravity="center"
android:text="@string/send" />
<!-- this one is new -->
<TextView
android:id="@+id/other"
android:layout_width="0dp"
android:layout_height="57dip"
android:layout_weight="1"
android:background="@drawable/toolbar_selector"
android:clickable="true"
android:drawablePadding="-12dp"
android:drawableTop="@drawable/ic_action_other"
android:gravity="center"
android:text="@string/other" />
</LinearLayout>
有。我现在很高兴。