2015-11-18 15 views
59

मेरे पास RecyclerView और ImageView के साथ एक गतिविधि है। मैं छवियों की सूची क्षैतिज रूप से दिखाने के लिए RecyclerView का उपयोग कर रहा हूं। जब मैं RecyclerView में ImageView में किसी छवि पर क्लिक करता हूं तो गतिविधि में छवि की एक बड़ी तस्वीर दिखानी चाहिए। अब तक सब कुछ ठीक काम करता है।रीसाइक्लर व्यू - विशेष स्थिति पर देखें

अब गतिविधि में दो और ImageButtons हैं: imageButton_left और imageButton_right। जब मैं imageButton_left पर क्लिक करता हूं, तो ImageView में छवि को बाएं मुड़ना चाहिए और RecyclerView में थंबनेल को इस परिवर्तन को प्रतिबिंबित करना चाहिए। imageButton_right के साथ ऐसा ही मामला है।

मैं ImageView घुमाने में सक्षम हूं। लेकिन, मैं RecyclerView में थंबनेल कैसे घुमा सकता हूं? मैं ViewHolder के ImageView कैसे प्राप्त कर सकता हूं?

कोड:

गतिविधि एक्सएमएल:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 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="match_parent" 
    android:orientation="vertical"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/recyclerview" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="10dp" /> 


    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="10dp" 
     android:orientation="vertical"> 

     <ImageView 
      android:id="@+id/original_image" 
      android:layout_width="200dp" 
      android:layout_height="200dp" 
      android:scaleType="fitXY" 
      android:src="@drawable/image_not_available_2" /> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="10dp" 
      android:gravity="center_horizontal" 
      android:orientation="horizontal"> 


      <ImageButton 
       android:id="@+id/imageButton_left" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_marginRight="20dp" 
       android:background="@drawable/rotate_left_icon" /> 

      <ImageButton 
       android:id="@+id/imageButton_right" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:background="@drawable/rotate_right_icon" /> 

     </LinearLayout> 
    </LinearLayout> 
</LinearLayout> 

मेरी गतिविधि कोड:

public class SecondActivity extends AppCompatActivity implements IRecyclerViewClickListener { 


    RecyclerView mRecyclerView; 
    LinearLayoutManager mLayoutManager; 
    RecyclerViewAdapter mRecyclerViewAdapter; 
    List<String> urls = new ArrayList<String>(); 
    ImageView mOriginalImageView; 
    ImageButton mLeftRotate, mRightRotate; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_second); 
     urls.clear(); 

     mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); 
     mLayoutManager = new LinearLayoutManager(this, android.support.v7.widget.LinearLayoutManager.HORIZONTAL, false); 
     mLayoutManager.setOrientation(android.support.v7.widget.LinearLayoutManager.HORIZONTAL); 
     mRecyclerView.setLayoutManager(mLayoutManager); 
     mRecyclerViewAdapter = new RecyclerViewAdapter(this, urls); 
     mRecyclerView.setAdapter(mRecyclerViewAdapter); 

     mOriginalImageView = (ImageView) findViewById(R.id.original_image); 
     mLeftRotate = (ImageButton) findViewById(R.id.imageButton_left); 
     mLeftRotate.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mOriginalImageView.setRotation(mOriginalImageView.getRotation() - 90); 
      } 
     }); 


     mRightRotate = (ImageButton) findViewById(R.id.imageButton_right); 
     mRightRotate.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mOriginalImageView.setRotation(mOriginalImageView.getRotation() + 90); 
      } 
     }); 

     Intent intent = getIntent(); 
     if (intent != null) { 

      String portfolio = intent.getStringExtra("portfolio"); 

      try { 

       JSONArray jsonArray = new JSONArray(portfolio); 

       for (int i = 0; i < jsonArray.length(); i++) { 

        JSONObject jsonObject = jsonArray.getJSONObject(i); 

        String url = jsonObject.getString("url"); 
        urls.add(url); 
       } 

       Log.d(Const.DEBUG, "URLs: " + urls.toString()); 

       mRecyclerViewAdapter.notifyDataSetChanged(); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 

    } 


    @Override 
    public void onItemClick(int position) { 
     Picasso.with(this).load(urls.get(position)).into(mOriginalImageView); 
    } 
} 

मेरा कस्टम RecyclerView के लिए एडाप्टर:

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

    Context context; 
    List<String> mUrls = new ArrayList<String>(); 

    IRecyclerViewClickListener mIRecyclerViewClickListener; 

    public int position; 

    public int getPosition() { 
     return position; 
    } 

    public void setPosition(int position) { 
     this.position = position; 
    } 



    public RecyclerViewAdapter(Context context, List<String> urls) { 
     this.context = context; 
     this.mUrls.clear(); 
     this.mUrls = urls; 

     Log.d(Const.DEBUG, "Urls Size: " + urls.size()); 
     Log.d(Const.DEBUG, urls.toString()); 

     if (context instanceof IRecyclerViewClickListener) 
      mIRecyclerViewClickListener = (IRecyclerViewClickListener) context; 
     else 
      Log.d(Const.DEBUG, "Implement IRecyclerViewClickListener in Activity"); 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(context).inflate(R.layout.item_horizontal_recyclerview, parent, false); 
     ViewHolder holder = new ViewHolder(view); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     Picasso.with(context).load(mUrls.get(position)).into(holder.mImageView); 
    } 

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


    public void rotateThumbnail() { 


    } 

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

     public ImageView mImageView; 
     public View v; 

     public ViewHolder(View v) { 
      super(v); 
      v.setTag(getAdapterPosition()); 
      v.setOnClickListener(this); 
      this.mImageView = (ImageView) v.findViewById(R.id.image); 
     } 

     @Override 
     public void onClick(View v) { 
      this.v = v; 
      mIRecyclerViewClickListener.onItemClick(getAdapterPosition()); 
     } 
    } 


} 
+1

आप अपने viewHolder निर्माता में यह सुनिश्चित करना चाहिए, है, तो बस अपने डेटा पर है कि संपत्ति को बदलने के लिए एक संपत्ति है कि आपको पता चलेगा कि छवि घुमाया जा करने की जरूरत है जोड़ सकते हैं और कॉल को सूचित करेंडेटासेट रीसाइक्लर बनाने के लिए चेंज किया गया देखें – Nanoc

+0

क्या कोई भी उत्तर आपकी समस्या का समाधान करता है? –

+0

व्यूहोल्डर प्रदर्शन समस्या के लिए स्थिर होना चाहिए। बाहरी वर्ग के सभी चर को कन्स्ट्रक्टर के माध्यम से पारित किया जाना चाहिए। – AppiDevo

उत्तर

73

मैं तुम्हें एक प्रयोग कर रहे हैं लगता हैसूची दिखाने के लिए 210। findViewByPosition नामक एक अच्छी विधि है कि

उस दृश्य को ढूंढता है जो दिए गए एडाप्टर स्थिति का प्रतिनिधित्व करता है।

आपको बस संपादित आइटम आप में रुचि रखते हैं की एडाप्टर स्थिति है

:। के रूप में टिप्पणी में पॉल Woitaschek द्वारा बताया गया है, findViewByPositionLayoutManager की एक विधि है, तो यह काम करेगा है सभी लेआउटमेनर्स (यानी StaggeredGridLayoutManager, आदि) के साथ

+3

वास्तव में वास्तव में एक विधि है 'लेआउटमैनेजर 'ताकि यह सभी लेआउट मैनेजर सबक्लास के लिए काम करेगा। –

+0

स्रोत कोड को देखा। LinearLayoutManger बैकिंग सरणी पर directAccess के माध्यम से देखता है जब प्रीलेआउट में नहीं होता है, जबकि रीसाइक्लर व्यू विधि हमेशा ट्रैवर्सल करता है। तो यह विधि अधिक कुशल है। – NameSpace

123

यही वह है जिसे आप देख रहे हैं।

मुझे यह समस्या भी थी। और आप की तरह, जवाब खोजने के लिए बहुत मुश्किल है। लेकिन व्यूहोल्डर को किसी विशिष्ट स्थिति से प्राप्त करने का एक आसान तरीका है (कुछ ऐसा जो आप एडाप्टर में शायद करेंगे)।

myRecyclerView.findViewHolderForAdapterPosition(pos);

नोट: देखें पुनर्नवीनीकरण किया गया है हैं, तो यह null वापस आ जाएगी। माइकल के लिए धन्यवाद मेरे महत्वपूर्ण चूक को जल्दी पकड़ने के लिए।

+3

यह वही है जो मैं लेआउटमैनेजर –

+3

में देख रहा था यह काम करता है, हालांकि, यदि आप 'व्यूहोल्डर' संदर्भित करने का प्रयास कर रहे हैं तो "रीसाइक्लिंग" था, तो यह 'शून्य' वापस आ जाएगा। – Michael

+0

@ माइकल, अच्छा पकड़ो! यह सब आप के लिए एक चेतावनी है, पहले शून्य के लिए परीक्षण (हाँ, एंड्रॉइड में बाकी सब कुछ की तरह)! –

13

आप View चाहते हैं, तो जैसे ViewHolder की itemView संपत्ति का उपयोग करने के लिए सुनिश्चित करें: myRecyclerView.findViewHolderForAdapterPosition(pos).itemView;

6

आप उपयोग उपयोग कर सकते हैं दोनों

recyclerViewInstance.findViewHolderForAdapterPosition(adapterPosition) और recyclerViewInstance.findViewHolderForLayoutPosition(layoutPosition)। सुनिश्चित करें कि पुनर्चक्रण दृश्य दृश्य दो प्रकार की स्थितियों का उपयोग करता है

एडाप्टर स्थिति: एडाप्टर में किसी आइटम की स्थिति। यह एडाप्टर के परिप्रेक्ष्य की स्थिति है। लेआउट स्थिति: नवीनतम लेआउट गणना में किसी आइटम की स्थिति। यह लेआउटमैनेजर के परिप्रेक्ष्य की स्थिति है। findViewHolderForLayoutPosition(layoutPosition) के लिए findViewHolderForAdapterPosition(adapterPosition) और getLayoutPosition() के लिए आपको getAdapterPosition() का उपयोग करना चाहिए।

रीसाइक्लिंग व्यू एडाप्टर और अन्य सदस्य चर में पहले चयनित आइटम स्थिति को पकड़ने के लिए सदस्य चर ले जाएं ताकि यह जांच सके कि उपयोगकर्ता पहली बार क्लिक कर रहा है या नहीं।

नमूना कोड और स्क्रीन शॉट नीचे दी गई अधिक जानकारी के लिए संलग्न हैं।

public class MainActivity extends AppCompatActivity {  

private RecyclerView mRecyclerList = null;  
private RecyclerAdapter adapter = null;  

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    mRecyclerList = (RecyclerView) findViewById(R.id.recyclerList);  
}  

@Override  
protected void onStart() {  
    RecyclerView.LayoutManager layoutManager = null;  
    String[] daysArray = new String[15];  
    String[] datesArray = new String[15];  

    super.onStart();  
    for (int i = 0; i < daysArray.length; i++){  
     daysArray[i] = "Sunday";  
     datesArray[i] = "12 Feb 2017";  
    }  

    adapter = new RecyclerAdapter(mRecyclerList, daysArray, datesArray);  
    layoutManager = new LinearLayoutManager(MainActivity.this);  
    mRecyclerList.setAdapter(adapter);  
    mRecyclerList.setLayoutManager(layoutManager);  
}  
}  


public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyCardViewHolder>{   

private final String TAG = "RecyclerAdapter";   
private Context mContext = null;   
private TextView mDaysTxt = null, mDateTxt = null;  
private LinearLayout mDateContainerLayout = null;  
private String[] daysArray = null, datesArray = null;  
private RecyclerView mRecyclerList = null;  
private int previousPosition = 0;  
private boolean flagFirstItemSelected = false;  

public RecyclerAdapter(RecyclerView mRecyclerList, String[] daysArray, String[] datesArray){  
    this.mRecyclerList = mRecyclerList;  
    this.daysArray = daysArray;  
    this.datesArray = datesArray;  
}  

@Override  
public MyCardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
    LayoutInflater layoutInflater = null;  
    View view = null;  
    MyCardViewHolder cardViewHolder = null;  
    mContext = parent.getContext();  
    layoutInflater = LayoutInflater.from(mContext);  
    view = layoutInflater.inflate(R.layout.date_card_row, parent, false);  
    cardViewHolder = new MyCardViewHolder(view);  
    return cardViewHolder;  
}  

@Override  
public void onBindViewHolder(MyCardViewHolder holder, final int position) {  
    mDaysTxt = holder.mDaysTxt;  
    mDateTxt = holder.mDateTxt;  
    mDateContainerLayout = holder.mDateContainerLayout;  

    mDaysTxt.setText(daysArray[position]);  
    mDateTxt.setText(datesArray[position]);  

    if (!flagFirstItemSelected){  
     mDateContainerLayout.setBackgroundColor(Color.GREEN);  
     flagFirstItemSelected = true;  
    }else {  
     mDateContainerLayout.setBackground(null);  
    }  
}  

@Override  
public int getItemCount() {  
    return daysArray.length;  
}  

class MyCardViewHolder extends RecyclerView.ViewHolder{  
    TextView mDaysTxt = null, mDateTxt = null;  
    LinearLayout mDateContainerLayout = null;  
    LinearLayout linearLayout = null;  
    View view = null;  
    MyCardViewHolder myCardViewHolder = null;  

    public MyCardViewHolder(View itemView) {  
     super(itemView);  
     mDaysTxt = (TextView) itemView.findViewById(R.id.daysTxt);  
     mDateTxt = (TextView) itemView.findViewById(R.id.dateTxt);  
     mDateContainerLayout = (LinearLayout) itemView.findViewById(R.id.dateContainerLayout);  

     mDateContainerLayout.setOnClickListener(new View.OnClickListener() {  
      @Override  
      public void onClick(View v) {  
       LinearLayout linearLayout = null;  
       View view = null;  

       if (getAdapterPosition() == previousPosition){  
        view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackgroundColor(Color.GREEN);  
        previousPosition = getAdapterPosition();  

       }else {  
        view = mRecyclerList.findViewHolderForAdapterPosition(previousPosition).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackground(null);  

        view = mRecyclerList.findViewHolderForAdapterPosition(getAdapterPosition()).itemView;  
        linearLayout = (LinearLayout) view.findViewById(R.id.dateContainerLayout);  
        linearLayout.setBackgroundColor(Color.GREEN);  
        previousPosition = getAdapterPosition();  
       }  
      }  
     });  
    }  
}  

} first element selected second element selected and previously selected item becomes unselected fifth element selected and previously selected item becomes unselected

+0

और मैंने सोचा कि यह चर्चा समाप्त हो गई है! इस मुद्दे को और स्पष्ट करने के लिए धन्यवाद। –

संबंधित मुद्दे