Android:导航抽屉内有2个或更多可扩展列表视图

13

我该如何做到像这样的功能?

在此输入图片描述

在导航抽屉里有两个可展开的列表视图。我试着将它添加到我的xml中,但没有成功。我的目标是创建一个只有一个滚动条的视图,但我不知道该怎么做。

这是我的导航抽屉布局:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/Bianco"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginRight="16dp"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="@string/tvHomeActions"
            android:id="@+id/textView" />

        <ExpandableListView
            android:id="@+id/elvHome"
            android:layout_width="match_parent"
            android:layout_marginTop="4dp"
            android:layout_height="300dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="@string/tvHomeNavigations"
            android:layout_marginTop="16dp"
            android:id="@+id/textView2" />

        <ExpandableListView
            android:id="@+id/elvNavigateTo"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="4dp"  />

    </LinearLayout>

</ScrollView>

编辑: 我想要创建类似 Gmail 应用中抽屉的东西。


2
我认为3是一个计数器,而不是项目内的项数。对于你的问题,我也认为没有2个不同的可扩展列表视图。将Title 1和Title 2视为分隔符,我不必编写如何添加它们的代码。 - user666
1
好的,但是如果你看一下LOG_TAG发布的截图,“item 3”有一个“3”,并且它是关闭的。我认为如果“Item 3”可以打开,它会像“Item 4”那样有3个子项。无论如何,现在我已经删除了所有内容,只添加了一个可扩展的列表视图。我认为关键在于可扩展列表视图中的组或头部视图。顺便说一句,对于我的英语,我很抱歉;) - crc_error
不,方框内的数字3表示按下该按钮后要查看的片段中有三个项目(例如按收件箱时显示4条未读消息)。 - AlleyOOP
2个回答

17

这里插入图片描述

终于搞定了!这是我创建的代码,用于获取带有分组标题的可展开列表视图(ExpandableListView)。现在我可以轻松地为标题、组和子项创建三个自定义xml布局。

对我而言它很有效,但我接受任何代码改进以优化内存使用、速度等方面。

// ---------------------------------------------------------------------------------------------
// NAVIGATION DRAWER SIDE FRAGMENT
// ---------------------------------------------------------------------------------------------

private ExpandableListView mDrawerListView;
private List<Elemento> mainActions = new ArrayList<>();
private HashMap<Integer, List<String>> childActions = new HashMap<>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.frg_navigation_drawer, container, false);

    assert v != null;

    mDrawerListView = (ExpandableListView) v.findViewById(R.id.elvHome);
    mDrawerListView.setGroupIndicator(null);

    // add first title
    mainActions.add(new TitoloGruppo("Good guys"));                     // 0
    mainActions.add(new Azione("Admiral Ackbar", "Dagobah System"));    // 1
    mainActions.add(new Azione("Han Solo", "Millenium Falcon"));        // 2
    mainActions.add(new Azione("Yoda", "Dagobah System"));              // 3
    // add second title
    mainActions.add(new TitoloGruppo("Bad guys"));                      // 4
    mainActions.add(new Azione("Emperor", "Death star 2"));             // 5
    mainActions.add(new Azione("Jabba", "Tatooine"));                   // 6
    mainActions.add(new Azione("Grand Moff Tarkin", "Death star 1"));   // 7

    // Adding child quotes to Ackbar
    List<String> mainSubFive = new ArrayList<>();
    mainSubFive.add("It's a trap!");

    // Adding child quotes to Yoda
    List<String> mainSubThree = new ArrayList<>();
    mainSubThree.add("Do or do not; there is no try.");
    mainSubThree.add("There is … another … Sky … walker.…");
    mainSubThree.add("When 900 years old you reach, look as good you will not ehh.");

    childActions.put(0, new ArrayList<String>());
    childActions.put(1, mainSubFive);
    childActions.put(2, new ArrayList<String>());
    childActions.put(3, mainSubThree);
    childActions.put(4, new ArrayList<String>());
    childActions.put(5, new ArrayList<String>());
    childActions.put(6, new ArrayList<String>());

    mDrawerListView.setAdapter(new ExpandableAdapter(getActivity(), mainActions, childActions));
    mDrawerListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            List<String> list = childActions.get(groupPosition);
            if(list.size() > 0)
                return false;
            else
                Toast.makeText(getActivity(), ""+ ((Azione) mainActions.get(groupPosition)).getSubtitle(), Toast.LENGTH_LONG).show();
            return false;
        }
    });

    mDrawerListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
            List<String> list = childActions.get(groupPosition);

            Toast.makeText(getActivity(), "" + list.get(childPosition).toString(), Toast.LENGTH_LONG).show();
            return false;
        }
    });
    return v;
}


// ---------------------------------------------------------------------------------------------
// INTERNAL CLASS
// ---------------------------------------------------------------------------------------------

protected class ExpandableAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<Elemento> mainElements;
    private HashMap<Integer, List<String>> childElements;
    private LayoutInflater vi;

    public ExpandableAdapter(Context context, List<Elemento> mainElements, HashMap<Integer, List<String>> childElements) {
        this.context = context;
        this.mainElements = mainElements;
        this.childElements = childElements;
        vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getGroupCount() {
        return this.mainElements.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        if(this.childElements.get(groupPosition) == null)
            return 0;
        return this.childElements.get(groupPosition).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this.mainElements.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return this.childElements.get(groupPosition).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        View v = convertView;

        final Elemento i = mainElements.get(groupPosition);
        if (i != null) {
            if(i.isGroupSection()){
                final TitoloGruppo si = (TitoloGruppo)i;
                v = vi.inflate(android.R.layout.simple_list_item_1, null);
                v.setOnClickListener(null);
                v.setOnLongClickListener(null);
                v.setLongClickable(false);
                final TextView sectionView = (TextView) v.findViewById(android.R.id.text1);
                sectionView.setTextColor(Color.parseColor("#FFC800"));
                sectionView.setText(si.getTitle());
            }else if(i.isAction()){
                Azione ei = (Azione)i;
                v = vi.inflate(android.R.layout.simple_list_item_2, null);
                final TextView title = (TextView)v.findViewById(android.R.id.text1);
                final TextView subtitle = (TextView)v.findViewById(android.R.id.text2);

                if (title != null)
                    title.setText(ei.title);
                if(subtitle != null)
                    subtitle.setText("count: " + getChildrenCount(groupPosition));
            }
        }
        return v;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(android.R.layout.simple_list_item_1, null);
        }

        TextView txtListChild = (TextView) convertView.findViewById(android.R.id.text1);
        txtListChild.setText(childText);
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}   

    public class TitoloGruppo implements Elemento {

    private final String titolo;

    public TitoloGruppo(String titolo) {
        this.titolo = titolo;
    }

    public String getTitle(){
        return titolo;
    }

    @Override
    public boolean isGroupSection() {
        return true;
    }

    @Override
    public boolean isAction() {
        return false;
    }
}

protected interface Elemento {
    public boolean isGroupSection();
    public boolean isAction();
}

protected class Azione implements Elemento {
    public final String title;
    public final String subtitle;

    public Azione(String title, String subtitle) {
        this.title = title;
        this.subtitle = subtitle;
    }

    public String getTitle() {
        return this.title;
    }

    public String getSubtitle() {
        return this.subtitle;
    }

    @Override
    public boolean isGroupSection() {
        return false;
    }

    @Override
    public boolean isAction() {
        return true;
    }
}

附注:感谢大家。


你能分享完整的源代码吗?还是它在活动中? - NovusMobile
嗨,活动代码是默认的Android Studio空白项目的代码。 - crc_error

8

提醒,你在问题中展示的屏幕截图也有固定或分组列表视图。

导航抽屉中的可扩展列表视图:

enter image description here

使用此代码DrawerLayoutTest来为导航抽屉中的可扩展列表视图添加功能。

更新:这正是您要寻找的内容,请尝试这个michenux导航抽屉Git

逻辑:

1>使用可扩展列表视图+michenux导航抽屉进行设计和可扩展列表视图,并且对于其中的3个项目计数,使用jgilfelt的android-viewbadger库。

2>您需要在列表视图的getview(..)中进行操作,以禁用/启用可扩展列表视图的下拉图标,如果该项没有子项(检查数组或arraylist是否为空),则使badger(下拉计数图标/badger)可见或不可见,只需更改每个项目的值的列表视图项布局即可。例如:对于包含可扩展子元素的列表行,使用不同的布局加载视图badger!

致谢:Michenaud,Jgilfelt


谢谢您的回答,我不认为我的截图与固定的列表视图有关。 我认为它是一个展开的列表视图(内部有3个项目的"TopView 4")在顶部和一个列表视图在底部。这正是我想要的。 我查看了您给出的链接,但那不是我寻找的东西。 再次感谢您的帮助;) - crc_error
我想要创建类似 Gmail 应用程序中的抽屉式菜单。 - crc_error
@crc_error,你需要在get view中进行调整,以禁用/启用可扩展列表视图的下拉图标。如果该项没有子项(检查数组或ArrayList是否为空),则需要使badger(下拉计数图标/badger)可见或不可见。就这样! - LOG_TAG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接