如何在导航抽屉片段中放置两个回收视图
How to place two recyclerviews in a navigation drawer fragment
所以我的 fragment
上的导航抽屉中有一个 recyclerview
,它工作正常。
但是我想添加第二个 recyclerview
列出更多项目。
这是可以实现的,但困难的部分是使整个布局一起滚动。
我已经 google 了,但还没有找到任何东西 helpful.I 我想也许你们中的一个人可以解决这个问题。
这可能吗?
FragmentDrawer.java
public class FragmentDrawer extends Fragment {
private static String TAG = FragmentDrawer.class.getSimpleName();
private RecyclerView recyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private NavigationDrawerAdapter adapter;
private View containerView;
private static String[] titles = null;
private FragmentDrawerListener drawerListener;
public FragmentDrawer() {
}
public void setDrawerListener(FragmentDrawerListener listener) {
this.drawerListener = listener;
}
public static List<NavDrawerItem> getData() {
List<NavDrawerItem> data = new ArrayList<>();
int[] icons = {R.drawable.home, R.drawable.ic_upcoming, R.drawable.ic_eventsaved, R.drawable.ic_wehappened, R.drawable.ic_persons};
// preparing navigation drawer items
for (int i = 0; i < titles.length && i < icons.length; i++) {
NavDrawerItem navItem = new NavDrawerItem();
navItem.setTitle(titles[i]);
navItem.setIcon(icons[i]);
data.add(navItem);
}
return data;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// drawer labels
titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating view layout
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new NavigationDrawerAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
drawerListener.onDrawerItemSelected(view, position);
mDrawerLayout.closeDrawer(containerView);
}
@Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
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();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
public interface FragmentDrawerListener {
public void onDrawerItemSelected(View view, int position);
}
NavigationDrawerAdapter.java
public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> {
List<NavDrawerItem> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
public void delete(int position) {
data.remove(position);
notifyItemRemoved(position);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.nav_drawer_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ImageView imgViewIcon;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
imgViewIcon = (ImageView) itemView.findViewById(R.id.item_icon);
}
}
}
strings.xml
<resources>
<string name="nav_item_home">Home</string>
<string name="nav_item_friends">Upcoming</string>
<string name="nav_item_notifications">Saved</string>
<string name="nav_item_main">weHappened</string>
<string name="nav_item_planners">Event planners</string>
<!-- navigation drawer item labels -->
<string-array name="nav_drawer_labels">
<item>@string/nav_item_home</item>
<item>@string/nav_item_friends</item>
<item>@string/nav_item_notifications</item>
<item>@string/nav_item_main</item>
<item>@string/nav_item_planners</item>
</string-array>
<string name="title_messages">Events saved</string>
<string name="title_friends">Upcoming events</string>
<string name="title_home">Home</string>
<string name="title_happened">Events weHappened</string>
<string name="title_planners">Event planners</string>
</resources>
如果您想在同一列表中列出更多项目,请使用单个 RecyclerView。使用 2 个不同的 RecyclerView 毫无意义,如果一个在另一个下面,则不能让它们一起滚动。
如果您想动态地向列表中添加更多项目,请在您的适配器中构建一个 "update" 方法,并在您想要添加更多项目时调用该方法并调用 notifyItemRangeChanged()(或最给定 RecyclerView.Adapter class)
的适当方法
编辑:
假设您设置了 RecyclerView 并且知道如何使用基本的 LinearLayoutManager 对其进行初始化和设置,我只想关注适配器。
因此,如果您想将 "Main options" 和 "Other options" 等 2 个类别分开,您可能需要考虑为 2 种视图类型实现适配器。这是一个关于如何实现这一点的简短代码片段,但这只强调了如何使用多种视图类型的想法。您可能希望根据需要对其进行修改:
public class DrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_HEADER = 0;
private static final int VIEW_TYPE_REGULAR_ITEM = 1;
private LayoutInflater mInflater;
private List<Object> mItems;
public DrawerAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mItems = new ArrayList<>();
mItems.add("Main options");
mItems.add(new Item("Option1", R.drawable.icons_for_option_1))
mItems.add(new Item("Option2", R.drawable.icons_for_option_2))
mItems.add(new Item("Option2", R.drawable.icons_for_option_2))
mItems.add(new Item("Option3", R.drawable.icons_for_option_3))
mItems.add("Secondary options")
mItems.add(new Item("Option4", R.drawable.icons_for_option_4))
// And so on...whatever the logic is.
}
@Override
public int getItemCount() {
return mItems.size();
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == 5) { // Assuming that the topmost item and the 5th item are the section headers. This if statement can be simplified too.
return VIEW_TYPE_HEADER;
} else {
return VIEW_TYPE_REGULAR_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) {
return new HeaderViewHolder(mInflater.inflate(R.layout.list_item_header, parent, false));
} else {
return new RegularItemViewHolder(mInflater.inflate(R.layout.list_item_regular, parent, false));
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof HeaderViewHolder) {
((HeaderViewHolder) holder).setup(mItems.get(position));
} else if (holder instanceof RegularItemViewHolder) {
((RegularItemViewHolder) holder).setup(mItems.get(position));
}
}
private static class RegularItemViewHolder extends RecyclerView.ViewHolder {
private RegularItemViewHolder(View convertView) {
super(convertView);
// Initialize your views here. Let's say you will have a TextView and an icon here or whatever else.
}
public void setup(Item item) {
// Update your views here, etc.
}
}
private static class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView titleTextView;
private HeaderViewHolder(View convertView) {
super(convertView);
titleTextView = convertView.findViewById(R.id.section_header);
}
public void setup(String sectionHeaderTitle) {
yourTextView.setText(title);
}
}
}
就是这样。对于最终的错误,我很抱歉,我没有测试代码。
干杯!
所以我的 fragment
上的导航抽屉中有一个 recyclerview
,它工作正常。
但是我想添加第二个 recyclerview
列出更多项目。
这是可以实现的,但困难的部分是使整个布局一起滚动。
我已经 google 了,但还没有找到任何东西 helpful.I 我想也许你们中的一个人可以解决这个问题。
这可能吗?
FragmentDrawer.java
public class FragmentDrawer extends Fragment {
private static String TAG = FragmentDrawer.class.getSimpleName();
private RecyclerView recyclerView;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private NavigationDrawerAdapter adapter;
private View containerView;
private static String[] titles = null;
private FragmentDrawerListener drawerListener;
public FragmentDrawer() {
}
public void setDrawerListener(FragmentDrawerListener listener) {
this.drawerListener = listener;
}
public static List<NavDrawerItem> getData() {
List<NavDrawerItem> data = new ArrayList<>();
int[] icons = {R.drawable.home, R.drawable.ic_upcoming, R.drawable.ic_eventsaved, R.drawable.ic_wehappened, R.drawable.ic_persons};
// preparing navigation drawer items
for (int i = 0; i < titles.length && i < icons.length; i++) {
NavDrawerItem navItem = new NavDrawerItem();
navItem.setTitle(titles[i]);
navItem.setIcon(icons[i]);
data.add(navItem);
}
return data;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// drawer labels
titles = getActivity().getResources().getStringArray(R.array.nav_drawer_labels);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflating view layout
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
adapter = new NavigationDrawerAdapter(getActivity(), getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
drawerListener.onDrawerItemSelected(view, position);
mDrawerLayout.closeDrawer(containerView);
}
@Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
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();
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
@Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public static interface ClickListener {
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
public interface FragmentDrawerListener {
public void onDrawerItemSelected(View view, int position);
}
NavigationDrawerAdapter.java
public class NavigationDrawerAdapter extends RecyclerView.Adapter<NavigationDrawerAdapter.MyViewHolder> {
List<NavDrawerItem> data = Collections.emptyList();
private LayoutInflater inflater;
private Context context;
public NavigationDrawerAdapter(Context context, List<NavDrawerItem> data) {
this.context = context;
inflater = LayoutInflater.from(context);
this.data = data;
}
public void delete(int position) {
data.remove(position);
notifyItemRemoved(position);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.nav_drawer_row, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
NavDrawerItem current = data.get(position);
holder.title.setText(current.getTitle());
holder.imgViewIcon.setImageResource(current.getIcon());
}
@Override
public int getItemCount() {
return data.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
public ImageView imgViewIcon;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
imgViewIcon = (ImageView) itemView.findViewById(R.id.item_icon);
}
}
}
strings.xml
<resources>
<string name="nav_item_home">Home</string>
<string name="nav_item_friends">Upcoming</string>
<string name="nav_item_notifications">Saved</string>
<string name="nav_item_main">weHappened</string>
<string name="nav_item_planners">Event planners</string>
<!-- navigation drawer item labels -->
<string-array name="nav_drawer_labels">
<item>@string/nav_item_home</item>
<item>@string/nav_item_friends</item>
<item>@string/nav_item_notifications</item>
<item>@string/nav_item_main</item>
<item>@string/nav_item_planners</item>
</string-array>
<string name="title_messages">Events saved</string>
<string name="title_friends">Upcoming events</string>
<string name="title_home">Home</string>
<string name="title_happened">Events weHappened</string>
<string name="title_planners">Event planners</string>
</resources>
如果您想在同一列表中列出更多项目,请使用单个 RecyclerView。使用 2 个不同的 RecyclerView 毫无意义,如果一个在另一个下面,则不能让它们一起滚动。
如果您想动态地向列表中添加更多项目,请在您的适配器中构建一个 "update" 方法,并在您想要添加更多项目时调用该方法并调用 notifyItemRangeChanged()(或最给定 RecyclerView.Adapter class)
的适当方法编辑:
假设您设置了 RecyclerView 并且知道如何使用基本的 LinearLayoutManager 对其进行初始化和设置,我只想关注适配器。
因此,如果您想将 "Main options" 和 "Other options" 等 2 个类别分开,您可能需要考虑为 2 种视图类型实现适配器。这是一个关于如何实现这一点的简短代码片段,但这只强调了如何使用多种视图类型的想法。您可能希望根据需要对其进行修改:
public class DrawerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_HEADER = 0;
private static final int VIEW_TYPE_REGULAR_ITEM = 1;
private LayoutInflater mInflater;
private List<Object> mItems;
public DrawerAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mItems = new ArrayList<>();
mItems.add("Main options");
mItems.add(new Item("Option1", R.drawable.icons_for_option_1))
mItems.add(new Item("Option2", R.drawable.icons_for_option_2))
mItems.add(new Item("Option2", R.drawable.icons_for_option_2))
mItems.add(new Item("Option3", R.drawable.icons_for_option_3))
mItems.add("Secondary options")
mItems.add(new Item("Option4", R.drawable.icons_for_option_4))
// And so on...whatever the logic is.
}
@Override
public int getItemCount() {
return mItems.size();
}
@Override
public int getItemViewType(int position) {
if (position == 0 || position == 5) { // Assuming that the topmost item and the 5th item are the section headers. This if statement can be simplified too.
return VIEW_TYPE_HEADER;
} else {
return VIEW_TYPE_REGULAR_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_HEADER) {
return new HeaderViewHolder(mInflater.inflate(R.layout.list_item_header, parent, false));
} else {
return new RegularItemViewHolder(mInflater.inflate(R.layout.list_item_regular, parent, false));
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof HeaderViewHolder) {
((HeaderViewHolder) holder).setup(mItems.get(position));
} else if (holder instanceof RegularItemViewHolder) {
((RegularItemViewHolder) holder).setup(mItems.get(position));
}
}
private static class RegularItemViewHolder extends RecyclerView.ViewHolder {
private RegularItemViewHolder(View convertView) {
super(convertView);
// Initialize your views here. Let's say you will have a TextView and an icon here or whatever else.
}
public void setup(Item item) {
// Update your views here, etc.
}
}
private static class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView titleTextView;
private HeaderViewHolder(View convertView) {
super(convertView);
titleTextView = convertView.findViewById(R.id.section_header);
}
public void setup(String sectionHeaderTitle) {
yourTextView.setText(title);
}
}
}
就是这样。对于最终的错误,我很抱歉,我没有测试代码。
干杯!