导航抽屉中的切换按钮

8
我正在尝试将一个切换按钮实现到导航抽屉项目中,这个项目可以由Android Studio自动生成。 最终我想要得到类似于这样的东西(“仅下载”按钮):

enter image description here

很不幸,我不知道如何在NavDrawer的ListView中添加切换按钮。我可能可以使用其中一个“自定义NavDrawer库”,但我想了解Google提出的自动生成示例的方式。

有关如何将其实现到默认的NavDrawer项目中的任何想法吗?


相同的问题有更简单、更规范的答案:https://dev59.com/yl0Z5IYBdhLWcg3w_0h8 - Rupert Rawnsley
1个回答

5
我会这样做:不使用ListView而是使用RecyclerView,然后我会创建三个不同的布局定义——带图标的标签、分隔线和带可选开关的标签。你的RecyclerView Adapter应该扩展Form RecyclerView.Adapter。对于这三个布局,你应该创建一个ViewHolder的自己实现。现在你需要为列表项创建几个类,并为它们所有的一个超级类。在你的Adapter中,你必须重写getViewType方法。明天当我上班时,我可以为你发布一些演示代码。
编辑:
activity_main.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="de.devhew.navigationdrawerexample.MainActivity">

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:popupTheme="@style/AppTheme.Toolbar.Overflow"
        app:theme="@style/AppTheme.Toolbar" />

    <FrameLayout
        android:id="@+id/main_content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

<fragment
    android:id="@+id/fragment_navigation_drawer"
    android:name="de.devhew.navigationdrawerexample.drawer.NavigationDrawerFragment"
    android:layout_width="280dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:layout="@layout/fragment_navigation_drawer"
    tools:layout="@layout/fragment_navigation_drawer" />

MainActivity.java

public class MainActivity extends ActionBarActivity {

private Toolbar toolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    toolbar = (Toolbar) findViewById(R.id.toolbar_main);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    List<NavDrawerEntry> drawerEntries = new ArrayList<>();
    drawerEntries.add(new NavDrawerItemWithIcon("Home", R.drawable.app_generic));
    drawerEntries.add(new NavDrawerItemWithIcon("People", R.drawable.app_generic));
    drawerEntries.add(new NavDrawerItemWithIcon("Stuff", R.drawable.app_generic));
    drawerEntries.add(new NavDrawerDivider());
    drawerEntries.add(new NavDrawerItem("Settings"));
    drawerEntries.add(new NavDrawerToggle("Wifi only"));

    NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
    drawerFragment.init((android.support.v4.widget.DrawerLayout) findViewById(R.id.drawer_layout),
            toolbar, drawerEntries);
}}

NavigationDrawerFragment.java

public class NavigationDrawerFragment extends Fragment {

private View root;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private RecyclerView mRecyclerView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    root = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
    return root;
}

public void init(DrawerLayout drawerLayout, final Toolbar toolbar, List<NavDrawerEntry> drawerEntries) {
    mDrawerLayout = drawerLayout;
    mDrawerToggle = new ActionBarDrawerToggle(getActivity(),
            drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            getActivity().invalidateOptionsMenu();
        }

        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            getActivity().invalidateOptionsMenu();
        }
    };

    mDrawerLayout.setDrawerListener(mDrawerToggle);
    mDrawerLayout.post(new Runnable() {
        @Override
        public void run() {
            mDrawerToggle.syncState();
        }
    });

    mRecyclerView = (RecyclerView) root.findViewById(R.id.nav_list);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    mRecyclerView.setHasFixedSize(true);

    NavigationDrawerAdapter adapter = new NavigationDrawerAdapter(getActivity(), drawerEntries);
    mRecyclerView.setAdapter(adapter);
}}

NavigationDrawerAdapter.java

public class NavigationDrawerAdapter
    extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<NavDrawerEntry> data;
private LayoutInflater inflater;

public NavigationDrawerAdapter(Context context, List<NavDrawerEntry> data) {
    this.data = data;
    this.inflater = LayoutInflater.from(context);
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

    View itemLayoutView;
    switch (viewType) {
        case 0:
            itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_item_with_icon, viewGroup, false);
            ItemWithIconVH holder = new ItemWithIconVH(itemLayoutView);
            return holder;
        case 1:
            itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_divider, viewGroup, false);
            DividerVH dividerViewHolder = new DividerVH(itemLayoutView);
            return dividerViewHolder;
        case 2:
            itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_item, viewGroup, false);
            ItemVH itemViewHolder = new ItemVH(itemLayoutView);
            return itemViewHolder;
        case 3:
            itemLayoutView = inflater.inflate(R.layout.layout_nav_drawer_toggle, viewGroup, false);
            ToggleVH toggleViewHolder = new ToggleVH(itemLayoutView);
            return toggleViewHolder;
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    final NavDrawerEntry item = data.get(position);

    if (item instanceof NavDrawerItemWithIcon) {
        ItemWithIconVH viewHolder = (ItemWithIconVH) holder;
        viewHolder.mTitle.setText(((NavDrawerItemWithIcon) item).getTitle());
        viewHolder.mImageView.setImageResource(((NavDrawerItemWithIcon) item).getIconId());
    }

    if (item instanceof NavDrawerItem) {
        ItemVH viewHolder = (ItemVH) holder;
        viewHolder.mTitle.setText(((NavDrawerItem) item).getTitle());
    }

    if (item instanceof NavDrawerToggle) {
        ToggleVH viewHolder = (ToggleVH) holder;
        viewHolder.mTitle.setText(((NavDrawerToggle) item).getTitle());
        viewHolder.mSwitch.setChecked(((NavDrawerToggle) item).isChecked());
    }
}

@Override
public int getItemViewType(int position) {
    if (data.get(position) instanceof NavDrawerItemWithIcon)
        return 0;

    if (data.get(position) instanceof NavDrawerDivider)
        return 1;

    if (data.get(position) instanceof NavDrawerItem)
        return 2;

    if (data.get(position) instanceof NavDrawerToggle)
        return 3;

    return -1;
}

@Override
public int getItemCount() {
    return data.size();
}

class ItemWithIconVH extends RecyclerView.ViewHolder {
    final TextView mTitle;
    final ImageView mImageView;

    public ItemWithIconVH(View itemView) {
        super(itemView);
        mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
        mImageView = (ImageView) itemView.findViewById(R.id.nav_item_image);
    }
}

class DividerVH extends RecyclerView.ViewHolder {
    public DividerVH(View itemView) {
        super(itemView);
    }
}

class ItemVH extends RecyclerView.ViewHolder {
    final TextView mTitle;

    public ItemVH(View itemView) {
        super(itemView);
        mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
    }
}

class ToggleVH extends RecyclerView.ViewHolder {
    final TextView mTitle;
    final Switch mSwitch;

    public ToggleVH(View itemView) {
        super(itemView);
        mTitle = (TextView) itemView.findViewById(R.id.nav_item_title);
        mSwitch = (Switch) itemView.findViewById(R.id.nav_switch);
    }
}}

所有导航抽屉项的超类:

public class NavDrawerEntry {}

没有图标的项目:

public class NavDrawerItem extends NavDrawerEntry {
private String title;

public NavDrawerItem(String title) {
    this.setTitle(title);
}

public String getTitle() {
    return title;
}

private void setTitle(String title) {
    this.title = title;
}}

带图标的项目:

public class NavDrawerItemWithIcon extends NavDrawerEntry {
private String title;
private int iconId;

public NavDrawerItemWithIcon(String title, int iconId) {
    this.setTitle(title);
    this.setIconId(iconId);
}

public int getIconId() {
    return iconId;
}

private void setIconId(int iconId) {
    this.iconId = iconId;
}

public String getTitle() {
    return title;
}

private void setTitle(String title) {
    this.title = title;
}}

分割线:

public class NavDrawerDivider extends NavDrawerEntry {}

带开关的项目:

public class NavDrawerToggle extends NavDrawerEntry {
private String title;
private boolean checked;

public NavDrawerToggle(String title) {
    this.setTitle(title);
}

public boolean isChecked() {
    return checked;
}

public void setChecked(boolean checked) {
    this.checked = checked;
}

public String getTitle() {
    return title;
}

private void setTitle(String title) {
    this.title = title;
}}

layout_nav_drawer_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:orientation="horizontal">

<TextView
    android:id="@+id/nav_item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="16dp"
    android:fontFamily="sans-serif"
    android:textColor="#000"
    android:textSize="16sp" /></LinearLayout>

layout_nav_drawer_item_with_icon.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true"
android:orientation="horizontal">

<ImageView
    android:id="@+id/nav_item_image"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="16dp"
    android:src="@drawable/app_generic" />

<TextView
    android:id="@+id/nav_item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="16dp"
    android:fontFamily="sans-serif"
    android:text="Verbundene Geräte"
    android:textColor="#000"
    android:textSize="16sp" /></LinearLayout>

layout_nav_drawer_divider.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#ddd"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp" /></LinearLayout>

layout_nav_drawer_toggle.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="60dp"
android:clickable="true">

<TextView
    android:id="@+id/nav_item_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_gravity="center_vertical"
    android:layout_marginLeft="16dp"
    android:fontFamily="sans-serif"
    android:text="Verbundene Geräte"
    android:textColor="#000"
    android:textSize="16sp" />

<Switch
    android:id="@+id/nav_switch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="16dp" /></RelativeLayout>

fragment_navigation_drawer.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="280dp"
android:layout_height="match_parent"
android:background="#eee"
tools:context="de.vacom.hew.materialdemo.NavigationDrawerFragment">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@color/primaryColor"
        android:elevation="3dp"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/nav_app_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="55dp"
            android:src="@drawable/app_generic" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="64dp"
            android:fontFamily="sans-serif-medium"
            android:text="Demo App"
            android:textColor="#eee"
            android:textSize="18sp" />

    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/nav_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout></FrameLayout>

那将是非常棒的,谢谢! 编辑:我已经尝试了几个小时来获取材料设计规则的L&F,最终使用了这个:https://github.com/mikepenz/MaterialDrawer 如果您可以以此示例为基础进行修改,我将非常感激。 :-) - sonovice
我的代码是对导航抽屉中不同项目的自己实现。很抱歉我看到你的编辑太晚了,不能进行修改。试试我的示例,也许能帮到你。 - HeW
非常感谢,我会仔细查看您的广泛编辑。如果可以的话,您能否将您的代码压缩并上传到某个地方?我尝试将所有内容复制到一个项目中,但仍然出现了很多错误... - sonovice
1
当然。这是链接。它是一个使用gradle的Android-Studio项目。https://drive.google.com/open?id=0B8CrX9jPxVAJNFJCRHlwR3MzbG8&authuser=0 - HeW
非常感谢,我会尝试将您的解决方案与我在编辑中提到的抽屉合并。它不是基于片段的,但希望我能够将其拼凑在一起。Herzlichen Dank ;-) - sonovice

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