【问题标题】:On navigation drawer item click, new list view in navigation drawer在导航抽屉项目单击时,导航抽屉中的新列表视图
【发布时间】:2015-09-15 05:38:42
【问题描述】:

我试图在导航抽屉中获得以下功能,但我无法打破它。

场景:-

我有一个导航抽屉。单击导航抽屉中的任何项目时,我需要打开一个列表视图,其中包含多个项目,可以进一步选择它以实现某种功能。 我还附上了图像,它将以适当的方式定义我的需求。请提供图片的参考以获得我基本上和实际需要的东西。

任何帮助将不胜感激..!

【问题讨论】:

  • 你为什么不想使用ExpandableListView?这将是您想要的最佳实践。
  • 您没有提到您的场景中没有发生什么问题?你想要右边的城市列表吗?或者您想要扩展菜单列表?请多解释
  • 最坏情况的解决方案是,使用两个具有线性布局方向的列表视图作为水平方向,并根据要求设置可见性可见和消失。但我想建议你使用 rom4ek 解决方案。
  • 您可以发布您的代码吗?

标签: android listview navigation slider navigation-drawer


【解决方案1】:

正如我看到你的图片,我理解的是,从你的抽屉里点击你想要另一个列表出现在它的右边。我说的对吗? 如果我更正,那么无法使用 ExpandableListView,因为 ExpandableListView 会在点击的项目下方生成项目。

所以一种解决方案是你可以取两个ListView。

抽屉内的第一个 ListView主要内容上的第二个,并为这两个 ListView 创建自定义适配器。

现在当用户单击抽屉列表项时,确定单击了哪个选项,例如 City、MyNews 或其他。

确定点击后,您可以根据用户点击的选项为第二个 ListView 填充适配器。并将该适配器应用于第二个 ListView 并通知它。

所以当用户从抽屉中点击另一个项目时,同样的事情会发生。但是第二个 ListView 的数据会发生变化。

我希望你明白我在说什么,这对你有帮助。

[更新]

好的,所以你的 xml 应该看起来像这样。

注意:我只是为此写一个骨架。

<!-- The main content view -->
<FrameLayout android:id="@+id/content_frame" />

<!-- The navigation drawer -->
<LinearLayout
    android:layout_gravity="start"
    android:orientation="horizontal">
    <ListView
        android:layout_weight="1"
        android:id="@+id/list1">
    </ListView>

    <ListView
        android:layout_weight="1"
        android:id="@+id/list2">
    </ListView>
</LinearLayout>

现在在您的 java 端。考虑两个列表视图都被引用为 list1list2 ,并且您创建了两个适配器 adapter1adapter2。 p>

使项目点击 list1 并应用如下逻辑...

list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {

        // now here you can get which option is clicked from list1.
        // using position and 
        int your_type = pos;

        adapter2.filderDataAccordingToType(your_type);
        // create the above method in your second adapter and pass your type like MyNews, City or any other.
        // and apply the logic of filtering by passing type to your method
        // your_type could be any data type i have take the integer.
        // and after filtering data you can notify your adapter.
        // so when the data of adpater gets changed your secondlistview get refreshed.
    }
});

就是这样。 希望对您有所帮助。

【讨论】:

  • 虽然它可能会有所帮助。将带有水平列表视图的线性布局放在抽屉中并休息您的逻辑。如果你能纠正它,请这样做。以便我接受你的回答。
  • 我有点困惑,您希望抽屉上的两个列表视图或抽屉上的一个列表视图和抽屉外的另一个列表视图..?这样我就可以正确更新答案...
  • 但是兄弟,如果您在一个抽屉中并排使用两个列表视图。它将为用户提供更少的空间,这作为 UX 部分不是一个好主意,否则你可以选择它。
【解决方案2】:

您可以使用creating a navigation drawer 上的 Android 开发者教程,但不要使用 ListView,而是使用ExpandableListView

例如,在该教程中,您可以看到在第一个代码块中他们使用了ListView。取而代之的是,将其更改为以下内容:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <ExpandableListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"/>
</android.support.v4.widget.DrawerLayout>

Android Hive 上的this 教程很好地解释了如何实现 ExpandableListView 适配器。我不会在这里粘贴他们的代码,因为这是一个很长的教程。如果您有任何问题,请在下方评论。

【讨论】:

    【解决方案3】:

    这是我的代码。

    • 我正在为子项目使用回收站视图。
    • 它正在向下扩展单词。
    • 我正在使用 2 个库。

      编译'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.7.1' 编译'com.wnafee:vector-compat:1.0.5'

    这里是导航抽屉片段

    public class NavigationDrawerFragment extends Fragment implements NavigationDrawerCallbacks {
    
    
    private static final String SAVED_STATE_EXPANDABLE_ITEM_MANAGER = "RecyclerViewExpandableItemManager";
    
    /**
     * Remember the position of the selected item.
     */
    private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
    
    /**
     * Per the design guidelines, you should show the drawer on launch until the user manually
     * expands it. This shared preference tracks this.
     */
    private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
    
    /**
     * A pointer to the current callbacks instance (the Activity).
     */
    private NavigationDrawerCallbacks mCallbacks;
    
    /**
     * Helper component that ties the action bar to the navigation drawer.
     */
    private ActionBarDrawerToggle mActionBarDrawerToggle;
    
    private DrawerLayout mDrawerLayout;
    private RecyclerView mDrawerList;
    private View mFragmentContainerView;
    
    private int mCurrentSelectedPosition = -1;
    private boolean mFromSavedInstanceState;
    private boolean mUserLearnedDrawer;
    
    private Subscription subscription;
    
    @Inject CategoryService categoryService;
    
    private MyExpandableItemAdapter expandableItemAdapter;
    private RecyclerView.Adapter wrappedAdapter;
    private RecyclerViewExpandableItemManager expandableItemManager;
    private LinearLayoutManager linearLayoutManager;
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DelhiShopApplication.component().inject(this);
    
        // Read in the flag indicating whether or not the user has demonstrated awareness of the
        // drawer. See PREF_USER_LEARNED_DRAWER for details.
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
        mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
    
        if (savedInstanceState != null) {
            mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
            mFromSavedInstanceState = true;
        }
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
        mDrawerList = (RecyclerView) view.findViewById(R.id.drawerList);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mDrawerList.setLayoutManager(layoutManager);
        mDrawerList.setHasFixedSize(true);
    
        if (mCurrentSelectedPosition != -1) {
            selectItem(mCurrentSelectedPosition);
        }
        return view;
    }
    
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    
        final Parcelable eimSavedState = (savedInstanceState != null) ? savedInstanceState.getParcelable(SAVED_STATE_EXPANDABLE_ITEM_MANAGER) : null;
        expandableItemManager = new RecyclerViewExpandableItemManager(eimSavedState);
    
    
    }
    
    private void setRecyclerView(Category category) {
        linearLayoutManager = new LinearLayoutManager(getActivity());
    
        final MyExpandableItemAdapter myItemAdapter = new MyExpandableItemAdapter(category);
        wrappedAdapter = expandableItemManager.createWrappedAdapter(myItemAdapter);
    
    
        final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
    
        // Change animations are enabled by default since support-v7-recyclerview v22.
        // Need to disable them when using animation indicator.
        animator.setSupportsChangeAnimations(false);
    
        mDrawerList.setLayoutManager(linearLayoutManager);
        mDrawerList.setAdapter(wrappedAdapter);  // requires *wrapped* adapter
        mDrawerList.setItemAnimator(animator);
        mDrawerList.setHasFixedSize(false);
    
        // additional decorations
        //noinspection StatementWithEmptyBody
    

    // if (supportsViewElevation()) { // // Lollipop 或更高版本具有原生投影功能。不需要 ItemShadowDecorator。 // } 别的 { // mDrawerList.addItemDecoration(new ItemShadowDecorator((NinePatchDrawable) getResources().getDrawable(R.drawable) // .material_shadow_z1))); // }

        expandableItemManager.attachRecyclerView(mDrawerList);
    }
    
    private boolean supportsViewElevation() {
        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
    }
    
    public boolean isDrawerOpen() {
        return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
    }
    
    public ActionBarDrawerToggle getActionBarDrawerToggle() {
        return mActionBarDrawerToggle;
    }
    
    public DrawerLayout getDrawerLayout() {
        return mDrawerLayout;
    }
    
    @Override
    public void onNavigationDrawerItemSelected(int position) {
        selectItem(position);
    }
    
    /**
     * Users of this fragment must call this method to set up the navigation drawer interactions.
     *
     * @param fragmentId   The android:id of this fragment in its activity's layout.
     * @param drawerLayout The DrawerLayout containing this fragment's UI.
     * @param toolbar      The Toolbar of the activity.
     */
    public void setup(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar) {
        mFragmentContainerView = (View) getActivity().findViewById(fragmentId).getParent();
        mDrawerLayout = drawerLayout;
    
        mDrawerLayout.setStatusBarBackgroundColor(getResources().getColor(R.color.myPrimaryDarkColor));
    
        mActionBarDrawerToggle = new ActionBarDrawerToggle(getActivity(), mDrawerLayout, toolbar, R.string
                .drawer_open, R.string.drawer_close) {
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                if (!isAdded()) {
                    return;
                }
    
                getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
            }
    
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                if (!isAdded()) {
                    return;
                }
                if (!mUserLearnedDrawer) {
                    mUserLearnedDrawer = true;
                    SharedPreferences sp = PreferenceManager
                            .getDefaultSharedPreferences(getActivity());
                    sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
                }
                getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
            }
        };
    
        // If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
        // per the navigation drawer design guidelines.
        if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
            mDrawerLayout.openDrawer(mFragmentContainerView);
        }
    
        // Defer code dependent on restoration of previous instance state.
        mDrawerLayout.post(new Runnable() {
            @Override
            public void run() {
                mActionBarDrawerToggle.syncState();
            }
        });
    
        mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
    }
    
    private void selectItem(int position) {
        mCurrentSelectedPosition = position;
        if (mDrawerLayout != null) {
            mDrawerLayout.closeDrawer(mFragmentContainerView);
        }
        if (mCallbacks != null) {
            mCallbacks.onNavigationDrawerItemSelected(position);
        }
        ((NavigationDrawerAdapter) mDrawerList.getAdapter()).selectPosition(position);
    }
    
    public void openDrawer() {
        mDrawerLayout.openDrawer(mFragmentContainerView);
    }
    
    public void closeDrawer() {
        mDrawerLayout.closeDrawer(mFragmentContainerView);
    }
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mCallbacks = (NavigationDrawerCallbacks) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
        }
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = null;
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
        if (expandableItemManager != null) {
            outState.putParcelable(
                    SAVED_STATE_EXPANDABLE_ITEM_MANAGER,
                    expandableItemManager.getSavedState());
        }
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Forward the new configuration the drawer toggle component.
        mActionBarDrawerToggle.onConfigurationChanged(newConfig);
    }
    
    public void setUserData(String user, String email, Bitmap avatar) {
        ((TextView) mFragmentContainerView.findViewById(R.id.txtUserEmail)).setText(email);
        ((TextView) mFragmentContainerView.findViewById(R.id.txtUsername)).setText(user);
    }
    
    public View getGoogleDrawer() {
        return mFragmentContainerView.findViewById(R.id.googleDrawer);
    }
    
    @Override
    public void onResume() {
        super.onResume();
        subscription = categoryService.getCategories()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Category>() {
                    @Override
                    public void call(Category category) {
                        // sadfksdjf
                        expandableItemAdapter = new MyExpandableItemAdapter(category);
                        mDrawerList.setAdapter(expandableItemAdapter);
                        setRecyclerView(category);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        // slkdfj
                    }
    
                });
    }
    
    
    @Override
    public void onPause() {
        subscription.unsubscribe();
        super.onPause();
    }
    
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (expandableItemManager != null) {
            expandableItemManager.release();
            expandableItemManager = null;
        }
    }
    

    这是我的可扩展项目适配器

    public class MyExpandableItemAdapter
        extends AbstractExpandableItemAdapter<MyExpandableItemAdapter.MyGroupViewHolder, MyExpandableItemAdapter.MyChildViewHolder> {
    private static final String TAG = "MyExpandableItemAdapter";
    
    private Category category;
    
    public static abstract class MyBaseViewHolder extends AbstractExpandableItemViewHolder {
        public ViewGroup mContainer;
        public View mDragHandle;
        public TextView mTextView;
    
        public MyBaseViewHolder(View v) {
            super(v);
            mContainer = (ViewGroup) v.findViewById(R.id.container);
            mDragHandle = v.findViewById(R.id.drag_handle);
            mTextView = (TextView) v.findViewById(android.R.id.text1);
    
            // hide the drag handle
            mDragHandle.setVisibility(View.GONE);
        }
    }
    
    public static class MyGroupViewHolder extends MyBaseViewHolder {
        public MorphButtonCompat mMorphButton;
    
        public MyGroupViewHolder(View v) {
            super(v);
            mMorphButton = new MorphButtonCompat(v.findViewById(R.id.indicator));
        }
    }
    
    public static class MyChildViewHolder extends MyBaseViewHolder {
        public MyChildViewHolder(View v) {
            super(v);
        }
    }
    
    public MyExpandableItemAdapter(Category dataProvider) {
        category = dataProvider;
    
        // ExpandableItemAdapter requires stable ID, and also
        // have to implement the getGroupItemId()/getChildItemId() methods appropriately.
        setHasStableIds(true);
    }
    
    @Override
    public int getGroupCount() {
        return category.getSubCategorySize();
    }
    
    @Override
    public int getChildCount(int groupPosition) {
        return getGroupCategoryAtPosition(groupPosition).getSubCategorySize();
    }
    
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return groupPosition * 100 + childPosition;
    }
    
    @Override
    public int getGroupItemViewType(int groupPosition) {
        return 0;
    }
    
    @Override
    public int getChildItemViewType(int groupPosition, int childPosition) {
        return 0;
    }
    
    @Override
    public MyGroupViewHolder onCreateGroupViewHolder(ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final View v = inflater.inflate(R.layout.list_group_item, parent, false);
        return new MyGroupViewHolder(v);
    }
    
    @Override
    public MyChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        final View v = inflater.inflate(R.layout.list_item, parent, false);
        return new MyChildViewHolder(v);
    }
    
    @Override
    public void onBindGroupViewHolder(MyGroupViewHolder holder, int groupPosition, int viewType) {
        // child item
    
        final Category groupItem = getGroupCategoryAtPosition(groupPosition);
    
        // set text
        holder.mTextView.setText(groupItem.getCategoryName());
    
        // mark as clickable
        holder.itemView.setClickable(true);
    
        // set background resource (target view ID: container)
        final int expandState = holder.getExpandStateFlags();
    
        if ((expandState & RecyclerViewExpandableItemManager.STATE_FLAG_IS_UPDATED) != 0) {
            int bgResId;
            MorphButton.MorphState indicatorState;
    
            if ((expandState & RecyclerViewExpandableItemManager.STATE_FLAG_IS_EXPANDED) != 0) {
                bgResId = R.drawable.bg_group_item_expanded_state;
                indicatorState = MorphButton.MorphState.END;
            } else {
                bgResId = R.drawable.bg_group_item_normal_state;
                indicatorState = MorphButton.MorphState.START;
            }
    
            holder.mContainer.setBackgroundResource(bgResId);
    
            if (holder.mMorphButton.getState() != indicatorState) {
                holder.mMorphButton.setState(indicatorState, true);
            }
        }
    }
    
    @Override
    public void onBindChildViewHolder(MyChildViewHolder holder, int groupPosition, int childPosition, int viewType) {
        // group item
        final Category childCategory = getChildCategory(groupPosition, childPosition);
        // set text
        holder.mTextView.setText(childCategory.getCategoryName());
    
        // set background resource (target view ID: container)
        int bgResId;
        bgResId = R.drawable.bg_item_normal_state;
        holder.mContainer.setBackgroundResource(bgResId);
    }
    
    
    @Override
    public boolean onCheckCanExpandOrCollapseGroup(MyGroupViewHolder holder, int groupPosition, int x, int y, boolean expand) {
    
        Category groupCategory = getGroupCategoryAtPosition(groupPosition);
    
        if (groupCategory.getSubCategorySize() == 0) {
            return false;
        }
    
        // check is enabled
        if (!(holder.itemView.isEnabled() && holder.itemView.isClickable())) {
            return false;
        }
    
        final View containerView = holder.mContainer;
        final View dragHandleView = holder.mDragHandle;
    
        final int offsetX = containerView.getLeft() + (int) (ViewCompat.getTranslationX(containerView) + 0.5f);
        final int offsetY = containerView.getTop() + (int) (ViewCompat.getTranslationY(containerView) + 0.5f);
    
        return !hitTest(dragHandleView, x - offsetX, y - offsetY);
    }
    
    private Category getGroupCategoryAtPosition(int groupPosition) {
        return category.getSubCategory().get(groupPosition);
    }
    
    private Category getChildCategory(int groupPosition, int childPosition) {
        return getGroupCategoryAtPosition(groupPosition).getSubCategory().get(childPosition);
    }
    
    
    public static boolean hitTest(View v, int x, int y) {
        final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f);
        final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f);
        final int left = v.getLeft() + tx;
        final int right = v.getRight() + tx;
        final int top = v.getTop() + ty;
        final int bottom = v.getBottom() + ty;
    
        return (x >= left) && (x <= right) && (y >= top) && (y <= bottom);
    }
    }
    

    这是我的 list_group_item.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    style="@style/commonListItemStyle"
    android:layout_width="match_parent"
    android:layout_height="96dp"
    android:layout_marginTop="8dp"
    android:background="#ffffff">
    
    <RelativeLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        tools:ignore="UselessParent">
    
        <View
            android:id="@+id/drag_handle"
            android:layout_width="32dp"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:background="#20000000"
            tools:ignore="RtlHardcoded" />
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_toRightOf="@id/drag_handle"
            android:gravity="center" />
    </RelativeLayout>
    
    </FrameLayout>
    

    list_item.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    style="@style/commonListItemStyle"
    android:layout_width="match_parent"
    android:layout_height="64dp"
    android:background="@drawable/bg_swipe_item_neutral">
    
    <RelativeLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        tools:ignore="UselessParent">
    
        <View
            android:id="@+id/drag_handle"
            android:layout_width="32dp"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:background="#20000000" />
    
        <TextView
            android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_toRightOf="@id/drag_handle"
            android:gravity="center"
            tools:ignore="RtlHardcoded" />
    </RelativeLayout>
    
    </FrameLayout>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-04
      • 1970-01-01
      • 2022-06-30
      • 2015-08-17
      • 2023-03-08
      相关资源
      最近更新 更多