9

Próbuję zaimplementować recyclerview że zachowuje się jak mój szkic poniżej:Tworzenie rozszerzalny RecyclerView

enter image description here

Chodzi o to, że istnieje lista rodzic, gdy element listy na liście dominującej stuknięty, element listy ujawnia listę podrzędną, która zawiera własne dane. gdy element listy zostanie dotknięty na liście podrzędnej, wartość tego elementu potomnego jest odzwierciedlana i aktualizuje wartość elementu nadrzędnego w elemencie listy nadrzędnej.

Próbowałem sprawić, aby działało przez ostatnie 3 dni bez skutku. Próbowałem używać AdvancedReyclerview library, ale dla początkującego, jak ja, był to gigantyczny bałagan, który nie miał sensu, szczególnie podczas przekazywania danych. Skopiowałem i wkleiłem pliki, których potrzebowałem, aby uzyskać minimalną działającą wersję, ale nie miałem pojęcia, jak przekazać moje dane do widoku recyklingu i jak zaktualizować go o nowo wybraną wartość.

Czy to możliwe, aby zrobić to, co próbuję zrobić, czy też jestem poza zasięgiem mojej głębi?

Jeśli nadal jest to trudne do zrozumienia, mogę to bardziej wyjaśnić.

EDYCJA: ktoś zalecił, że robię to z ExpandableListView zamiast RecyclerView. Jakieś myśli na ten temat?

Odpowiedz

0

To jest trochę późno, ale spójrz na tej zaawansowanej recyclerview biblioteki https://github.com/h6ah4i/android-advancedrecyclerview

w ich dokumentacji można zobaczyć rozbudowy punkt zajęcia związane/Interfaces to sprawdzić.

+0

Spartan, sprawdziłem ich przykładem, ale okazało się to trudne do naśladowania. Co muszę dodać do projektu, aby zacząć korzystać z jego rozszerzonej biblioteki? Czy jest coś jeszcze poza katalogiem kompilacji, czy muszę skopiować pliki z lib do mojego projektu? –

+1

@A_Matar jest jeszcze jeden prosty przykład, z którego możesz uzyskać trochę pomysłu na tworzenie http://anandbose.github.io/android_recyclerview_expandablelistview.html – Spartan

2

Można sprawdzić moją bibliotekę w here

I stworzyć coś jak poniżej kodu:

public class PurchaseItemRecyclerViewAdapter extends ExpandableRecyclerView.Adapter<PurchaseItemRecyclerViewAdapter.ChildViewHolder,ExpandableRecyclerView.SimpleGroupViewHolder,String,String> 
{ 

List<ItemModel> itemModels; 

public PurchaseItemRecyclerViewAdapter() { 
    this.itemModels = new ArrayList<>(); 
    itemModels.add(new ItemModel("group 0",3,"subitem :")); 
    itemModels.add(new ItemModel("group 1",3,"subitem :")); 
    itemModels.add(new ItemModel("group 2",2,"subitem :")); 
    itemModels.add(new ItemModel("group 3",1,"subitem :")); 
    itemModels.add(new ItemModel("group 4",3,"subitem :")); 
    itemModels.add(new ItemModel("group 5",5,"subitem :")); 
} 

@Override 
public int getGroupItemCount() { 
    return itemModels.size(); 
} 

@Override 
public int getChildItemCount(int i) { 
    return itemModels.get(i).getSubItemCount(); 
} 

@Override 
public String getGroupItem(int i) { 
    return itemModels.get(i).getParentName(); 
} 

@Override 
public String getChildItem(int group, int child) { 
    return itemModels.get(group).getSubItemPrefix() + child; 
} 

@Override 
protected ExpandableRecyclerView.SimpleGroupViewHolder onCreateGroupViewHolder(ViewGroup parent) 
{ 
    return new ExpandableRecyclerView.SimpleGroupViewHolder(parent.getContext()); 
} 

@Override 
protected ChildViewHolder onCreateChildViewHolder(ViewGroup parent, int viewType) 
{ 
    View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.purchase_list_content,parent,false); 
    return new ChildViewHolder(rootView); 
} 

@Override 
public void onBindGroupViewHolder(ExpandableRecyclerView.SimpleGroupViewHolder holder, int group) { 
    super.onBindGroupViewHolder(holder, group); 
    holder.setText(getGroupItem(group)); 

} 

@Override 
public void onBindChildViewHolder(ChildViewHolder holder, final int group, int position) 
{ 
    super.onBindChildViewHolder(holder, group, position); 
    holder.name.setText(getChildItem(group, position)); 
    holder.itemView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      itemModels.get(group).setParentName("edited Parent"); 
      notifyItemChanged(group); 
     } 
    }); 
} 

@Override 
public int getChildItemViewType(int i, int i1) { 
    return 1; 
} 

public class ChildViewHolder extends RecyclerView.ViewHolder 
{ 
    private TextView name; 
    public ChildViewHolder(View itemView) { 
     super(itemView); 
     name = (TextView) itemView.findViewById(R.id.item_name); 
    } 
} 
} 

a ta klasa ItemModel:

public class ItemModel { 
String parentName; 
int subItemCount; 
String subItemPrefix; 

public ItemModel(String parentName, int subItemCount, String subItemPrefix) { 
    this.parentName = parentName; 
    this.subItemCount = subItemCount; 
    this.subItemPrefix = subItemPrefix; 
} 

public String getParentName() { 
    return parentName; 
} 

public void setParentName(String parentName) { 
    this.parentName = parentName; 
} 

public int getSubItemCount() { 
    return subItemCount; 
} 

public void setSubItemCount(int subItemCount) { 
    this.subItemCount = subItemCount; 
} 

public String getSubItemPrefix() { 
    return subItemPrefix; 
} 

public void setSubItemPrefix(String subItemPrefix) { 
    this.subItemPrefix = subItemPrefix; 
} 
} 
1

można łatwo osiągnąć za pomocą tej library, istnieje pełny przykład: here.

Zasadniczo grupować przedmioty na sekcje:

class MySection extends StatelessSection { 

    String header; 
    List<String> list; 
    boolean expanded = true; 

    public MySection(String header, List<String> list) { 
     // call constructor with layout resources for this Section header and items 
     super(R.layout.section_header, R.layout.section_item); 
     this.myHeader = header; 
     this.myList = list; 
    } 

    @Override 
    public int getContentItemsTotal() { 
     return expanded? list.size() : 0; 
    } 

    @Override 
    public RecyclerView.ViewHolder getHeaderViewHolder(View view) { 
     return new HeaderViewHolder(view); 
    } 

    @Override 
    public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) { 
     final HeaderViewHolder headerHolder = (HeaderViewHolder) holder; 

     headerHolder.tvTitle.setText(title); 

     headerHolder.rootView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       expanded = !expanded; 
       headerHolder.imgArrow.setImageResource(
         expanded ? R.drawable.ic_keyboard_arrow_up_black_18dp : R.drawable.ic_keyboard_arrow_down_black_18dp 
       ); 
       sectionAdapter.notifyDataSetChanged(); 
      } 
     }); 
    } 

    @Override 
    public RecyclerView.ViewHolder getItemViewHolder(View view) { 
     // return a custom instance of ViewHolder for the items of this section 
     return new MyItemViewHolder(view); 
    } 

    @Override 
    public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) { 
     MyItemViewHolder itemHolder = (MyItemViewHolder) holder; 

     // bind your view here 
     itemHolder.tvItem.setText(list.get(position)); 
    } 
} 

Następnie należy utworzyć instancję sekcjami i konfigurowania adaptera:

// Create an instance of SectionedRecyclerViewAdapter 
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter(); 

// Add your Sections 
sectionAdapter.addSection(new MySection("A", Arrays.asList(new String[] {"a", "b", "c" }))); 
sectionAdapter.addSection(new MySection("B", Arrays.asList(new String[] {"d", "e", "f" }))); 

// Set up your RecyclerView with the SectionedRecyclerViewAdapter 
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); 
recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
recyclerView.setAdapter(sectionAdapter); 
2

1.ExpandableRecyclerAdapter.class

public abstract class ExpandableRecyclerAdapter<T extends ExpandableRecyclerAdapter.ListItem> extends RecyclerView.Adapter<ExpandableRecyclerAdapter.ViewHolder> { 
    protected Context mContext; 
    protected List<T> allItems = new ArrayList<>(); 
    protected List<T> visibleItems = new ArrayList<>(); 
    private List<Integer> indexList = new ArrayList<>(); 
    private SparseIntArray expandMap = new SparseIntArray(); 
    private int mode; 

    protected static final int TYPE_HEADER = 1000; 

    private static final int ARROW_ROTATION_DURATION = 150; 

    public static final int MODE_NORMAL = 0; 
    public static final int MODE_ACCORDION = 1; 

    public ExpandableRecyclerAdapter(Context context) { 
    mContext = context; 
    } 

    public static class ListItem { 
    public int ItemType; 

    public ListItem(int itemType) { 
     ItemType = itemType; 
    } 
    } 

    @Override 
    public long getItemId(int i) { 
    return i; 
    } 

    @Override 
    public int getItemCount() { 
    return visibleItems == null ? 0 : visibleItems.size(); 
    } 

    protected View inflate(int resourceID, ViewGroup viewGroup) { 
    return LayoutInflater.from(mContext).inflate(resourceID, viewGroup, false); 
    } 

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

    public class HeaderViewHolder extends ViewHolder { 
    ImageView arrow; 

    public HeaderViewHolder(View view) { 
     super(view); 

     view.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       toggleExpandedItems(getLayoutPosition(),false); 
       /*if(isExpanded(getLayoutPosition())){ 
        collapseItems(getLayoutPosition(),false); 
       }else { 
        expandItems(getLayoutPosition(),true); 
       }*/ 
      } 
     }); 
    } 

    public HeaderViewHolder(View view, final ImageView arrow) { 
     super(view); 

     this.arrow = arrow; 

     arrow.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       handleClick(); 
      } 
     }); 
    } 

    protected void handleClick() { 
     if (toggleExpandedItems(getLayoutPosition(), false)) { 
      openArrow(arrow); 
     } else { 
      closeArrow(arrow); 
     } 
    } 

    public void bind(int position) { 
     arrow.setRotation(isExpanded(position) ? 90 : 0); 
    } 
    } 

    public boolean toggleExpandedItems(int position, boolean notify) { 
    if (isExpanded(position)) { 
     collapseItems(position, notify); 
     return false; 
    } else { 
     expandItems(position, notify); 

     if (mode == MODE_ACCORDION) { 
      collapseAllExcept(position); 
     } 

     return true; 
    } 
    } 

    public void expandItems(int position, boolean notify) { 
    int count = 0; 
    int index = indexList.get(position); 
    int insert = position; 

    for (int i=index+1; i<allItems.size() && allItems.get(i).ItemType != TYPE_HEADER; i++) { 
     insert++; 
     count++; 
     visibleItems.add(insert, allItems.get(i)); 
     indexList.add(insert, i); 
    } 

    notifyItemRangeInserted(position + 1, count); 

    int allItemsPosition = indexList.get(position); 
    expandMap.put(allItemsPosition, 1); 

    if (notify) { 
     notifyItemChanged(position); 
    } 
} 

public void collapseItems(int position, boolean notify) { 
    int count = 0; 
    int index = indexList.get(position); 

    for (int i=index+1; i<allItems.size() && allItems.get(i).ItemType != TYPE_HEADER; i++) { 
     count++; 
     visibleItems.remove(position + 1); 
     indexList.remove(position + 1); 
    } 

    notifyItemRangeRemoved(position + 1, count); 

    int allItemsPosition = indexList.get(position); 
    expandMap.delete(allItemsPosition); 

    if (notify) { 
     notifyItemChanged(position); 
    } 
    } 


protected boolean isExpanded(int position) { 
    int allItemsPosition = indexList.get(position); 
    return expandMap.get(allItemsPosition, -1) >= 0; 
} 

@Override 
public int getItemViewType(int position) { 
    return visibleItems.get(position).ItemType; 
} 

public void setItems(List<T> items) { 
    allItems = items; 
    List<T> visibleItems = new ArrayList<>(); 
    expandMap.clear(); 
    indexList.clear(); 

    for (int i=0; i<items.size(); i++) { 
     if (items.get(i).ItemType == TYPE_HEADER) { 
      indexList.add(i); 
      visibleItems.add(items.get(i)); 
     } 
    } 

    this.visibleItems = visibleItems; 
    notifyDataSetChanged(); 
    } 



protected void removeItemAt(int visiblePosition) { 
    int allItemsPosition = indexList.get(visiblePosition); 

    allItems.remove(allItemsPosition); 
    visibleItems.remove(visiblePosition); 

    incrementIndexList(allItemsPosition, visiblePosition, -1); 
    incrementExpandMapAfter(allItemsPosition, -1); 

    notifyItemRemoved(visiblePosition); 
} 

private void incrementExpandMapAfter(int position, int direction) { 
    SparseIntArray newExpandMap = new SparseIntArray(); 

    for (int i=0; i<expandMap.size(); i++) { 
     int index = expandMap.keyAt(i); 
     newExpandMap.put(index < position ? index : index + direction, 1); 
    } 

    expandMap = newExpandMap; 
    } 

    private void incrementIndexList(int allItemsPosition, int visiblePosition, int direction) { 
    List<Integer> newIndexList = new ArrayList<>(); 

    for (int i=0; i<indexList.size(); i++) { 
     if (i == visiblePosition) { 
      if (direction > 0) { 
       newIndexList.add(allItemsPosition); 
      } 
     } 

     int val = indexList.get(i); 
     newIndexList.add(val < allItemsPosition ? val : val + direction); 
     } 

    indexList = newIndexList; 
    } 

    public void collapseAll() { 
    collapseAllExcept(-1); 
    } 

    public void collapseAllExcept(int position) { 
    for (int i=visibleItems.size()-1; i>=0; i--) { 
     if (i != position && getItemViewType(i) == TYPE_HEADER) { 
      if (isExpanded(i)) { 
       collapseItems(i, true); 
      } 
     } 
    } 
    } 

    public void expandAll() { 
    for (int i=visibleItems.size()-1; i>=0; i--) { 
     if (getItemViewType(i) == TYPE_HEADER) { 
      if (!isExpanded(i)) { 
       expandItems(i, true); 
      } 
     } 
    } 
    } 

    public static void openArrow(View view) { 
    view.animate().setDuration(ARROW_ROTATION_DURATION).rotation(180); 

    } 

    public static void closeArrow(View view) { 
    view.animate().setDuration(ARROW_ROTATION_DURATION).rotation(0); 
    } 

    public int getMode() { 
    return mode; 
    } 

    public void setMode(int mode) { 
    this.mode = mode; 
    } 
} 

2.activity_main

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 

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

3.item_header

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:orientation="horizontal" 
android:padding="@dimen/standard_padding"> 

<LinearLayout 
    android:id="@+id/lnr_1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerHorizontal="true"> 

    <TextView 
     android:id="@+id/txt_header_address" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:drawableLeft="@mipmap/ic_usa" 
     android:gravity="center" 
     android:text="Beverly Hills" 
     android:textStyle="bold" /> 

</LinearLayout> 

<ImageView 
    android:id="@+id/img_arrow" 
    android:layout_width="@dimen/arrow_size" 
    android:layout_height="@dimen/arrow_size" 
    android:layout_alignParentRight="true" 
    android:src="@mipmap/arrow" /> 

<TextView 
    android:id="@+id/txt_header_name" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" 
    android:layout_centerVertical="true" 
    android:text="Home" 
    android:textStyle="bold" /> 

4.item_content.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:orientation="vertical"> 

<RelativeLayout 
    android:id="@+id/rcl_header_btn" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <Button 
     style="?android:attr/borderlessButtonStyle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/btn_cancle" /> 

    <Button 
     style="?android:attr/borderlessButtonStyle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:text="@string/btn_save" /> 

</RelativeLayout> 

<LinearLayout 
    android:id="@+id/lnr_parent" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/rcl_header_btn" 
    android:gravity="center_vertical" 
    android:orientation="vertical"> 

    <EditText 
     android:id="@+id/edt_description" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="DESCRIPTION" /> 

    <EditText 
     android:id="@+id/edt_address" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="Address" /> 

    <LinearLayout 
     android:id="@+id/lnr_child_1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <EditText 
      android:id="@+id/edt_city" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:hint="City" /> 

     <EditText 
      android:id="@+id/edt_state" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:hint="State" /> 

    </LinearLayout> 

    <LinearLayout 
     android:id="@+id/lnr_child_2" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <EditText 
      android:id="@+id/edt_zipcode" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:hint="Zip Code" /> 

     <EditText 
      android:id="@+id/edt_country" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:hint="Country" /> 

    </LinearLayout> 
</LinearLayout> 

<RelativeLayout 
    android:id="@+id/rcl_bottom" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/lnr_parent"> 

    <CheckBox 
     android:id="@+id/chk_marked" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBaseline="@+id/txt_type" /> 

    <TextView 
     android:id="@+id/txt_type" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBaseline="@+id/btn_delete" 
     android:layout_toRightOf="@+id/chk_marked" 
     android:gravity="center" 
     android:text="SET AS DEFAULT" /> 

    <Button 
     android:id="@+id/btn_delete" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:text="DELETE" /> 

</RelativeLayout> 

5.Adapter

public class PeopleAdapter extends ExpandableRecyclerAdapter<PeopleAdapter.PeopleListItem> { 
public static final int TYPE_PERSON = 1001; 

public PeopleAdapter(Context context) { 
    super(context); 

    setItems(getSampleItems()); 
} 

public static class PeopleListItem extends ExpandableRecyclerAdapter.ListItem { 
    public String Text; 

    public PeopleListItem(String group) { 
     super(TYPE_HEADER); 

     Text = group; 
    } 

    public PeopleListItem(String first, String last) { 
     super(TYPE_PERSON); 

     Text = first + " " + last; 
    } 
    } 

    public class HeaderViewHolder extends ExpandableRecyclerAdapter.HeaderViewHolder { 
    TextView name; 

    public HeaderViewHolder(View view) { 
     super(view, (ImageView) view.findViewById(R.id.img_arrow)); 

     name = (TextView) view.findViewById(R.id.txt_header_name); 
    } 

    public void bind(int position) { 
     super.bind(position); 

     name.setText(visibleItems.get(position).Text); 
    } 
    } 

    public class PersonViewHolder extends ExpandableRecyclerAdapter.ViewHolder { 
    EditText name; 

    public PersonViewHolder(View view) { 
     super(view); 

     name = (EditText) view.findViewById(R.id.edt_description); 
    } 

    public void bind(int position) { 
     name.setText(name.getText()); 
    } 

    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    switch (viewType) { 
     case TYPE_HEADER: 
      return new HeaderViewHolder(inflate(R.layout.item_header, parent)); 
     case TYPE_PERSON: 
     default: 
      return new PersonViewHolder(inflate(R.layout.item_content, parent)); 
    } 
    } 

    @Override 
    public void onBindViewHolder(ExpandableRecyclerAdapter.ViewHolder holder, int position) { 
    switch (getItemViewType(position)) { 
     case TYPE_HEADER: 
      ((HeaderViewHolder) holder).bind(position); 
      break; 
     case TYPE_PERSON: 
     default: 
      ((PersonViewHolder) holder).bind(position); 
      break; 
    } 
    } 

    private List<PeopleListItem> getSampleItems() { 
    List<PeopleListItem> items = new ArrayList<>(); 
    items.add(new PeopleListItem("Friends")); 
    items.add(new PeopleListItem("", "")); 
    items.add(new PeopleListItem("Friends")); 
    items.add(new PeopleListItem("", "")); 
    return items; 
} 

}

6.MainActivity.java

public class MainActivity extends AppCompatActivity { 
RecyclerView recycler; 
PeopleAdapter adapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    recycler = (RecyclerView) findViewById(R.id.main_recycler); 

    adapter = new PeopleAdapter(this); 
    adapter.setMode(ExpandableRecyclerAdapter.MODE_ACCORDION); 
    recycler.setLayoutManager(new LinearLayoutManager(this)); 
    recycler.setAdapter(adapter); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    super.onCreateOptionsMenu(menu); 

    getMenuInflater().inflate(R.menu.menu_main, menu); 

    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.action_expand_all: 
      adapter.expandAll(); 
      return true; 
     case R.id.action_collapse_all: 
      adapter.collapseAll(); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
    } 
} 
}