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