2015-02-18 10 views
25

Ich entwickle eine Android-Anwendung für Online-Shopping. Ich habe folgende Ansicht zur Liste der Produkte erstellt RecyclerView mit, dass ich das Bild ändern zur Auswahl Option Menüpunkt will: zum Ändern LayoutAndroid RecyclerView: Layout-Datei LIST zu GRID onOptionItemSelected

Ich habe erstellt folgenden AdapterProductAdapter genannt, daß ich habe implementiert Code in onCreateViewHolder für die Auswahl der Layout-Datei basierend auf booleschen Wert.

Code of Adapter ProductAdapter:

/*** 
    * ADAPTER for Product to binding rows in List 
    */ 
    private class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductRowHolder> { 

     private List<Product> productList; 

     private Context mContext; 

     public ProductAdapter(Context context, List<Product> feedItemList) { 
      this.productList = feedItemList; 
      this.mContext = context; 
     } 

     @Override 
     public ProductRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
      View v = LayoutInflater.from(viewGroup.getContext()).inflate(isProductViewAsList ? R.layout.product_row_layout_list : R.layout.product_row_layout_grid, null); 
      ProductRowHolder mh = new ProductRowHolder(v); 
      return mh; 
     } 

     @Override 
     public void onBindViewHolder(ProductRowHolder productRowHolder, int i) { 
      Product prodItem = productList.get(i); 

//   Picasso.with(mContext).load(feedItem.getName()) 
//     .error(R.drawable.ic_launcher) 
//     .placeholder(R.drawable.ic_launcher) 
//     .into(productRowHolder.thumbnail); 


      double price = prodItem.getPrice(); 
      double discount = prodItem.getDiscount(); 
      double discountedPrice = price - (price * discount/100); 

      String code = ""; 
      if(prodItem.getCode() != null) 
       code = "[" + prodItem.getCode() + "] "; 

      productRowHolder.prodIsNewView.setVisibility(prodItem.getIsNew() == 1 ? View.VISIBLE : View.INVISIBLE); 
      productRowHolder.prodNameView.setText(code + prodItem.getName()); 
      productRowHolder.prodOriginalRateView.setText("Rs." + new BigDecimal(price).setScale(2,RoundingMode.DOWN)); 
      productRowHolder.prodDiscView.setText("" + new BigDecimal(discount).setScale(2,RoundingMode.DOWN) + "% off"); 
      productRowHolder.prodDiscRateView.setText("Rs." + new BigDecimal(discountedPrice).setScale(2,RoundingMode.DOWN)); 

      productRowHolder.prodOriginalRateView.setPaintFlags(productRowHolder.prodOriginalRateView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 
     } 

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

     public class ProductRowHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 
      //Declaration of Views 

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

       view.setOnClickListener(this); 

       //Find Views 
      } 

      @Override 
      public void onClick(View view) { 
       //Onclick of row 
      } 
     } 
    } 

Danach habe ich Code getan für das Ändern RecyclerView Layout von List zu Grid und Vice Versa in onOptionsItemSelected, hier rufe ich mAdapter.notifyDataSetChanged(); so wird es Adapter erneut aufrufen und Wert ändern.

onOptionsItemSelected:

@Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     switch (id) { 
      case R.id.action_settings: 
       return true; 
      case android.R.id.home: 
       finish(); 
       break; 
      case R.id.product_show_as_view: 
       isProductViewAsList = !isProductViewAsList; 
       supportInvalidateOptionsMenu(); 
       mRecyclerView.setLayoutManager(isProductViewAsList ? new LinearLayoutManager(this) : new GridLayoutManager(this, 2)); 
       mAdapter.notifyDataSetChanged(); 
       break; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

Ich habe wenig Erfolg wie:

Bild von Grid Layout:

enter image description here

Bild von List Layout:

enter image description here

aber jetzt, wenn ich scrollen und dann ändert sich VIEW wie angezeigt:

Grid Layout:

enter image description here

List Layout:

enter image description here

Ich weiß nicht, warum es nach dem Scrollen passiert. Gibt es eine andere Möglichkeit, die Ansicht so zu ändern?

Heute habe ich gerade gesehen, dass dieses Problem wegen ImageView ist, ohne dass es perfekt funktioniert.

Hilfe bitte, Sie helfen wird geschätzt.

+1

Diese Antwort helfen könnte tauschen: http://stackoverflow.com/a/24933117/2649012 –

+0

Nutzung diese RecyclerView.setHasFixedSize (true); –

+0

seine 'mRecyclerView.setHasFixedSize (true);' aber nicht für mich arbeiten. irgendeine andere Lösung? –

Antwort

22

gefunden I-Lösung mit dem Starten der Tätigkeit I LinearLayoutManager wie eingestellt haben:

mLayoutManager = new LinearLayoutManager(this); 
mProductListRecyclerView.setLayoutManager(mLayoutManager); 

danach onOptionsItemSelected geschrieben wie:

case R.id.menu_product_change_view: 
    isViewWithCatalog = !isViewWithCatalog; 
    supportInvalidateOptionsMenu(); 
    //loading = false; 
    mProductListRecyclerView.setLayoutManager(isViewWithCatalog ? new LinearLayoutManager(this) : new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); 
    mProductListRecyclerView.setAdapter(mAdapter); 
    break; 

und Ändern Ansicht in onCreateViewHolder wie :

Von Anfang bis Ende müssen Sie isViewWithCatalog Variable für die Anzeige des Layouts zuerst verwalten.

+0

Was ist 'isViewWithCatalog' wie man das bekommt? – R2R

+0

@ R2R 'isViewWithCatalog' ist eine in dieser Aktivität definierte boolesche Variable, die entscheidet, welches Layout zuerst kommt. –

6

Ich löste dieses Problem, indem ich den Adapter nach dem Ändern des Layoutmanagers erneut auf RecyclerView setzte.

+0

Nach dem Scrollen zu 30-40 Elemente und dann, wenn ich versuche, die Ansicht zu ändern, und es wird wieder mit 1 Position zu scrollen beginnen. Gibt es dafür eine Lösung? –

+0

@ PratikButani, versuchen Sie RecyclerView.scrollToPosition (Position) zu verwenden; Nach dem Einstellen des neuen LayoutManagers. –

+0

Wie kann ich die Adapterposition wiederherstellen? Ich denke über eine Methode, die die letzte Position speichern zu schaffen bekam es von onBindViewHolder aber immer noch denkt, gibt es eine bessere Art und Weise – crgarridos

1

Ich denke, nach dem Scrollen und zurück zur Rasteransicht geändert, wird das erste Element nicht neu erstellt. Ich löste dies durch Überschreiben getItemViewType() und die Layout-Dateien in onCreateViewHolder entsprechend aufblasen.

4

In diesem SDK samples gibt es ein komplettes Beispiel aber es verwendet eine Layout-Datei für beide LayoutManagers

Für die Scroll-Position zu halten, wenn das Layout Schalten sie diese Funktion verwendet

public void setRecyclerViewLayoutManager(LayoutManagerType layoutManagerType) { 
    int scrollPosition = 0; 

    // If a layout manager has already been set, get current scroll position. 
    if (mRecyclerView.getLayoutManager() != null) { 
     scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager()) 
       .findFirstCompletelyVisibleItemPosition(); 
    } 

    switch (layoutManagerType) { 
     case GRID_LAYOUT_MANAGER: 
      mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT); 
      mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER; 
      break; 
     case LINEAR_LAYOUT_MANAGER: 
      mLayoutManager = new LinearLayoutManager(getActivity()); 
      mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER; 
      break; 
     default: 
      mLayoutManager = new LinearLayoutManager(getActivity()); 
      mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER; 
    } 

    mRecyclerView.setLayoutManager(mLayoutManager); 
    mRecyclerView.scrollToPosition(scrollPosition); 
} 
0

i viewflipper und Änderung verwenden Geben Sie eine Liste mit Animationen ein. und schön .

in Haupt xml

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

<ViewFlipper android:id="@+id/view_flipper" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/small_list" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> 
    <android.support.v7.widget.RecyclerView android:scrollbarStyle="insideInset" 
     android:id="@+id/big_list" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> 
    <android.support.v7.widget.RecyclerView android:scrollbarStyle="insideInset" 
     android:id="@+id/grid_list" android:paddingLeft="2.0dip" android:paddingRight="2.0dip" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" /> 
</ViewFlipper> 

aller Code in Tätigkeit

private RecyclerView smallRecycleView; 
private RecyclerView gridRecycleView; 
private RecyclerView bigRecycleView; 

private StaggeredGridLayoutManager gridLayoutManager; 
private LinearLayoutManager bigLayoutManager; 
private LinearLayoutManager smallLayoutManager; 

private AAdapter adapterGrid; 
private AAdapter adapterSmall; 
private AAdapter adapterBig; 

private ViewFlipper viewFlipper; 


private TypeShow typeShowList = TypeShow.Small; 


private AList list = null; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    setLayout(R.layout.main_layout); 
    super.onCreate(savedInstanceState); 

    try { 

     list = getItems(10); 


     viewFlipper = ((ViewFlipper)findViewById(R.id.view_flipper)); 
     viewFlipper.setOutAnimation(MainActivity.this, R.anim.anim_fade_out_flip); 
     viewFlipper.setInAnimation(MainActivity.this, R.anim.anim_fade_in_flip); 

     smallRecycleView = ((RecyclerView)findViewById(R.id.small_list)); 
     gridRecycleView = ((RecyclerView)findViewById(R.id.grid_list)); 
     bigRecycleView = ((RecyclerView)findViewById(R.id.big_list)); 

     smallRecycleView.setHasFixedSize(false); 
     gridRecycleView.setHasFixedSize(false); 
     bigRecycleView.setHasFixedSize(false); 

     smallLayoutManager = new LinearLayoutManager(MainActivity.this); 
     smallRecycleView.setLayoutManager(smallLayoutManager); 
     gridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); 
     gridRecycleView.setLayoutManager(gridLayoutManager); 
     gridRecycleView.setItemAnimator(null); 
     bigLayoutManager = new LinearLayoutManager(MainActivity.this); 
     bigRecycleView.setLayoutManager(bigLayoutManager); 


     adapterSmall = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Small); 
     smallRecycleView.setAdapter(adapterSmall); 

     adapterGrid = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Grid); 
     gridRecycleView.setAdapter(adapterGrid); 

     adapterBig = new AAdapter(MainActivity.this,list,MainActivity.this,TypeShow.Big); 
     bigRecycleView.setAdapter(adapterBig); 





     if (Build.VERSION.SDK_INT >= 11) 
     { 
      smallRecycleView.setVerticalScrollbarPosition(1); 
      gridRecycleView.setVerticalScrollbarPosition(1); 
      bigRecycleView.setVerticalScrollbarPosition(1); 
     } 

     final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.floating_action_button); 
       fab.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          smallRecycleView.setSelected(false); 
          bigRecycleView.setSelected(false); 
          gridRecycleView.setSelected(false); 
          viewFlipper.showNext(); 

          if(typeShowList == TypeShow.Small){ 
           typeShowList = TypeShow.Big; 
           fab.setImageResource(R.drawable.ic_type_grid); 
          } 
          else if(typeShowList == TypeShow.Big){ 
           typeShowList = TypeShow.Grid; 
           fab.setImageResource(R.drawable.ic_atype_small); 
          } 
          else { 
           typeShowList = TypeShow.Small; 
           fab.setImageResource(R.drawable.ic_type_big); 
          } 
         } 
       }); 
     fab.setImageResource(R.drawable.ic_type_big); 

    } 
    catch (Exception e){ 
    } 
} 

Typ

public enum TypeShow { 
Grid, 
Small, 
Big } 

Adapter

public class AAdapter extends RecyclerView.Adapter<AAdapter.PersonViewHolder> { 

private AList noteList = null; 
private MainActivity mContext; 
private TypeShow typeShow; 

public AAdapter(MainActivity mContext, AList noteList, OnItemClickListener mListener, TypeShow typeShow){ 
    this.noteList = noteList; 
    this.mContext= mContext; 
    this.mListener= mListener; 
    this.typeShow= typeShow; 
} 

@Override 
public int getItemCount() { 
    return noteList.size(); 
} 

@Override 
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
    if(typeShow == TypeShow.Grid) { 
     View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_grid, viewGroup, false); 
     return new PersonViewHolder(v); 
    } 
    else if(typeShow == TypeShow.Small) { 

     View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_small, viewGroup, false); 
     return new PersonViewHolder(v); 
    } 
    else { 
     View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_row_big, viewGroup, false); 
     return new PersonViewHolder(v); 
    } 
} 


@Override 
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) { 
} 


public static class PersonViewHolder extends RecyclerView.ViewHolder { 

    PersonViewHolder(View itemView) { 
     super(itemView); 

    } 
} 
} 
+1

Während dieser Code-Schnipsel, die Frage lösen kann, [einschließlich einer Erklärung] (// meta.stackexchange.com/ Fragen/114762/Erklären-vollständig-Code-basierte Antworten) hilft wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in der Zukunft beantworten, und diese Leute könnten die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch nicht, Ihren Code mit erklärenden Kommentaren zu füllen, dies reduziert die Lesbarkeit sowohl des Codes als auch der Erklärungen! – kayess

0

sollten Sie zwei Adapter machen ein jeder seine eigene oncreateviewholder Implementierung und dann Recycler Ansicht swapadapter Methode verwenden, um die Adapter