2

我开发了一个基于Material Design的导航抽屉,其中包含Header视图,请参阅本教程:How To Make Material Design Navigation Drawer With Header View带分隔符的RecyclerView导航抽屉

我想添加一个类别名称下面的分隔符,但似乎有与我的分隔符相对应的数据集的位置有问题。这意味着分隔符正确加载,但不在我想要的位置。 基本上我试图做的是将“DrawerItem”对象的ArrayList传递给扩展RecyclerView的“MyAdapter”类。 ArrayList包含所有内容: - 标题的参数 - 项目名称和图标 - 和分隔符,也将它自己设计为DrawerItem对象,但只有一个字符串作为标题(在本例中为“Others”)。

这是我的代码:

DrawerItem:

package madapps.materialdesignappbar; 

public class DrawerItem { 

    String ItemName; 
    int imgResID; 
    String title; 

    String name ; 
    String email ; 
    int profile ; 

public DrawerItem(String Name, String Email, int profileResID){ 
    name = Name; 
    email = Email; 
    profile = profileResID; 
} 

public DrawerItem(String itemName, int imgResID) { 
    ItemName = itemName; 
    this.imgResID = imgResID; 
} 
//separator case 
public DrawerItem(String title) { 
    this(null, 0); 
    this.title = title; 
    this.ItemName = "separator"; 
} 

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

public String getItemName() { 
    return ItemName; 
} 

public int getImgResID() { 
    return imgResID; 
} 

public void setItemName(String itemName) { 
    this.ItemName = itemName; 
} 

public void setImgResID(int imgResID) { 
    this.imgResID = imgResID; 
} 

public void setName(String Name){ 
    this.name = Name; 
} 

public void setEmail(String Email){ 
    this.email = Email; 
} 

public void setProfile(int Profile){ 
    this.profile = Profile; 
} 

public String getName(){ 
    return name; 
} 
public String getEmail(){ 
    return email; 
} 
public int getProfile(){ 
    return profile; 
} 

} 

MyAdapter

package madapps.materialdesignappbar; 

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

private static final int TYPE_HEADER = 0; // Declaring Variable to Understand which View is being worked on 
// IF the view under inflation and population is header or Item 
private static final int TYPE_ITEM = 1; 
private static final int TYPE_SEPARATOR = 2; 

private ArrayList<DrawerItem> data; 

MyAdapter(ArrayList<DrawerItem> Data){ 
    // MyAdapter Constructor with titles and icons parameter 
    // titles, icons, name, email, profile pic are passed from the main activity as we have seen earlier 
    data = Data; 
} 
// Creating a ViewHolder which extends the RecyclerView View Holder 
// ViewHolder are used to to store the inflated views in order to recycle them 
public static class ViewHolder extends RecyclerView.ViewHolder { 
    int Holderid; 

    LinearLayout itemLayout; 
    TextView textView; 
    ImageView imageView; 
    ImageView profile; 
    TextView Name; 
    TextView email; 
    TextView drawerTitle; 
    LinearLayout separatorLayout; 
    // Creating ViewHolder Constructor with View and viewType As a parameter 
    public ViewHolder(View itemView, int ViewType) { 
     super(itemView); 
     // Here we set the appropriate view in accordance with the 
     // the view type as passed when the holder object is created 
     if (ViewType == TYPE_HEADER){ 
      Name = (TextView) itemView.findViewById(R.id.name);   // Creating Text View object from header.xml for name 
      email = (TextView) itemView.findViewById(R.id.email);   // Creating Text View object from header.xml for email 
      profile = (ImageView) itemView.findViewById(R.id.circleView); // Creating Image view object from header.xml for profile pic 

      Holderid = 0; // Setting holder id = 0 as the object being populated are of type header view 
     } 
     if(ViewType == TYPE_ITEM) { 

      textView = (TextView) itemView.findViewById(R.id.rowText); // Creating TextView object with the id of textView from item_row.xml 
      imageView = (ImageView) itemView.findViewById(R.id.rowIcon); // Creating ImageView object with the id of ImageView from item_row.xml 

      Holderid = 1;             // setting holder id as 1 as the object being populated are of type item row 
     } 
     if(ViewType == TYPE_SEPARATOR){ 
      drawerTitle = (TextView) itemView.findViewById(R.id.drawerTitle); 

      Holderid = 2; 
     } 
    } 
} 

//Below first we Override the method onCreateViewHolder which is called when the ViewHolder is 
//Created, In this method we inflate the item_row.xml layout if the viewType is Type_ITEM or else we inflate header.xml 
// if the viewType is TYPE_HEADER 
// and pass it to the view holder 
@Override 
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    if (viewType == TYPE_HEADER) { 
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false); //Inflating the layout 
     ViewHolder vhHeader = new ViewHolder(v,viewType); //Creating ViewHolder and passing the object of type view 

     return vhHeader; //returning the object created 
    }else 

    if (viewType == TYPE_ITEM) { 
      View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false); //Inflating the layout 
      ViewHolder vhItem = new ViewHolder(v, viewType); //Creating ViewHolder and passing the object of type view 
      return vhItem; // Returning the created object 
      //inflate your layout and pass it to view holder 
    } 
    if (viewType == TYPE_SEPARATOR){ 
     View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.separator, parent, false); 
     ViewHolder vhSeparator = new ViewHolder(v, viewType); 

     return vhSeparator; 
    } 

    return null; 
} 
/* Next we override a method which is called when the item in a row is needed to be displayed, 
@param position tells us item at which position is being constructed to be displayed 
@param holder  id of the holder object tell us which view type is being created 1 for item row */ 
@Override 
public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) { 

    if(holder.Holderid==0) { 
     holder.profile.setImageResource(data.get(0).getProfile()); // Similarly we set the resources for header view 
     holder.Name.setText(data.get(0).getName()); 
     holder.email.setText(data.get(0).getEmail()); 
    } 
    if(holder.Holderid == 1) { 
      // as the list view is 1going to be called after the header view so we decrement the 

     holder.textView.setText(data.get(position).title); 
     holder.imageView.setImageResource(data.get(position).imgResID); 

    }if (holder.Holderid==2){ 
     holder.drawerTitle.setText(data.get(4).getItemName()); 
    } 
} 

// This method returns the number of items present in the list 
@Override 
public int getItemCount() { 
    return data.size(); 
} 
// With the following method we check what type of view is being passed 
@Override 
public int getItemViewType(int position) { 
    if (isPositionHeader(position)) {//if position == 0 return true 
     return TYPE_HEADER;  //0 
    } 
    if(isSeparator(position)){ 
     return TYPE_SEPARATOR; 
    } 
     return TYPE_ITEM; 
} 
private boolean isSeparator(int position){ 
    return position==2; 
} 
private boolean isPositionHeader(int position) { 
    return position == 0; 
} 

} 

正如你看到的我是填充DrawerItem的ArrayList中有三种对象,按上述顺序(代码MainActivity):

ArrayList data = new ArrayList<DrawerItem>(); 

    data.add(new DrawerItem("Chris Benois","[email protected]",R.mipmap.aka)); 

    data.add(new DrawerItem("Home",R.mipmap.ic_home)); 
    data.add(new DrawerItem("Events",R.mipmap.ic_events)); 
    data.add(new DrawerItem("Mail", R.mipmap.ic_mail)); 
    data.add(new DrawerItem("Others")); 
    data.add(new DrawerItem("Shop", R.mipmap.ic_shop)); 
    data.add(new DrawerItem("Travel", R.mipmap.ic_travel)); 

的问题是,我的“分隔符”分隔符不上来,我希望它是(之前的“商店”项) ,但在其他地方,因为这图所示:

Navigation Drawer

我怎样才能移动它,我想?

回答

3

不知道你是否已经找到了解决方案,但由于你的问题帮助我回收者的观点,我想我会看看我是否能够回报这个优惠。

我发现ViewHolder类中最重要的方法是getItemViewType(int position)。在您发布的代码中,您似乎要为TYPE_SEPARATOR返回2,而没有正确检查导航抽屉中元素的位置,这就是为什么您的分隔线出现在导航抽屉的家中。您需要检查第五个位置,然后返回TYPE_SEPARATOR。

我曾经在我的抽屉隔板通过创建一个新的布局,当它击中了我的第六元素通过传递ViewHolder不同的类型:

public int getItemViewType(int position) { 
    if (position == 0) { 
     return TYPE_HEADER; 
    } else if (position>0 && position <6) { 
     return TYPE_TAG; 
    } else if (position ==6) { 
     return TYPE_DIVIDER; 
    } 
    else 
     return TYPE_ICON; 


} 

,并在我的ViewHolder构造:

public ViewHolder(View itemView, int viewType) { 
     super(itemView); 


     if(viewType == TYPE_HEADER) 
     { 

      name = (TextView) itemView.findViewById(R.id.name); 
      email = (TextView) itemView.findViewById(R.id.email); 
      profile = (ImageView) itemView.findViewById(R.id.image_view); 
      holderId = 0; 

     } 

     if (viewType == TYPE_TAG) 
     { 

      tagText = (TextView) itemView.findViewById(R.id.tag); 
      holderId = 1; 


     } 

     if(viewType == TYPE_ICON) 
     { 
      iconText = (TextView) itemView.findViewById(R.id.rowText); 
      icon = (ImageView) itemView.findViewById(R.id.rowIcon); 
      holderId = 2; 


     } 

     if(viewType == TYPE_DIVIDER) 
     { 
      dividerText = (TextView) itemView.findViewById(R.id.rowText); 
      dividerIcon = (ImageView) itemView.findViewById(R.id.rowIcon); 


      holderId = 3; 
     } 


    } 

} 

和在我的onCreateViewHolder方法中,我刚刚为TYPE_DIVIDER充了一个不同的布局。

希望它有帮助。

编辑

我已经自创建以来工作的回收观点,我不建议夸大你的分频器不同的布局。它给我造成了各种各样的问题。你应该使用RecyclerView.ItemDecoration。这里是SO,How to add dividers and spaces between items in RecyclerView?上的一些很棒的帖子。

+0

它也帮助了我。谢谢;) – 2015-04-13 14:15:26

+0

我可以看到你的'TYPE_DIVIDER'layout?或者我们只需要添加一个分隔符代码? – Mohsen 2015-06-30 06:24:10

+0

对不起,AndroidDev,我最终放弃了回收站视图,所以我不再有布局。我不能确切地记得为什么。我认为这只是占用我太多的时间来正确实施。 – JupiterT 2015-07-07 21:24:53