2012-02-27 13 views
6

मैं एंड्रॉइड में Instagram ऐप जैसे ListView के कस्टम सेक्शन या हेडर को कैसे कार्यान्वित कर सकता हूं।एंड्रॉइड लिस्टव्यू कस्टम सेक्शन हैडर

http://prsarahevans.com/wp-content/uploads/2011/06/photo.PNG

जब बार है कि Userpic, नाम और समय अभी भी वहाँ हो सकता है और जब अन्य हेडर बार यह पास जाना तो यह धक्का तरह चेतन ऊपर तक स्क्रॉल करें।

धन्यवाद।

उत्तर

9

मैं सूचीदृश्य पर स्क्रॉल श्रोता का उपयोग करके इस समस्या को हल करने में सक्षम था। (2.1 पर परीक्षण किया गया)

प्रत्येक सूची पंक्ति के लिए कहें कि मेरे पास नीचे जैसा एक लेआउट है। एक सामग्री भाग और एक हेडर भाग है। इससे कोई फ़र्क नहीं पड़ता कि आप हेडर या सामग्री के लिए किस प्रकार का उपयोग करते हैं।

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" android:background="#FFFFFF"> 

    <ImageView 
     android:id="@+id/content" 
     android:layout_width="fill_parent" 
     android:layout_height="300dp" 
     android:scaleType="centerCrop" 
     android:src="@drawable/pic" 
     android:background="#aaaaff" 
     android:layout_marginTop="40dp"/> 

    <TextView 
     android:id="@+id/header" 
     android:layout_width="fill_parent" 
     android:layout_height="40dp" 
     android:padding="12dp" 
     android:text="Deneme Row" 
     android:textColor="#000000" 
     android:background="#99ffffff"/> 
</RelativeLayout> 

गतिविधि के लिए परीक्षण लेआउट निम्नलिखित में है:

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

    <ListView 
     android:id="@+id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 
    </ListView> 
</LinearLayout> 

अंत में गतिविधि के लिए कोड नीचे दी गई है। यहां मुझे एक एडाप्टर होना था जो हेडर व्यू को स्टोर करने के लिए व्यूहोल्डर का उपयोग करता था और प्रत्येक चरम स्क्रॉल इवेंट्स (पिछली टॉप) के लिए स्क्रॉल में बदलाव का ट्रैक रखने के लिए एक चर भी था। यह इस तथ्य के कारण है कि offsetTopAndBottom() इसके पिछले स्थान से संबंधित दृश्य के ऑफसेट को बदल देता है।

public class TestActivity extends Activity implements AbsListView.OnScrollListener{ 

    ListView list; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     list = (ListView) findViewById(R.id.list); 
     list.setAdapter(new Adapter(this));   
     list.setOnScrollListener(this); 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) {  
     //the listview has only few children (of course according to the height of each child) who are visible 
     for(int i=0; i < list.getChildCount(); i++){ 
      View child = list.getChildAt(i); 
      ViewHolder holder = (ViewHolder) child.getTag(); 

      //if the view is the first item at the top we will do some processing 
      if(i == 0){    
       boolean isAtBottom = child.getHeight() <= holder.header.getBottom(); 
       int offset = holder.previousTop - child.getTop(); 
       if(!(isAtBottom && offset > 0)){      
        holder.previousTop = child.getTop(); 
        holder.header.offsetTopAndBottom(offset);     
        holder.header.invalidate(); 
       } 
      } //if the view is not the first item it "may" need some correction because of view re-use 
      else if (holder.header.getTop() != 0) { 
       int offset = -1 * holder.header.getTop(); 
       holder.header.offsetTopAndBottom(offset); 
       holder.previousTop = 0; 
       holder.header.invalidate(); 
      } 
     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) {} 

    private static class Adapter extends ArrayAdapter<String> { 
     public Adapter(Context context) { 
      super(context, R.layout.row, R.id.header); 
      for(int i=0; i < 50; i++){ 
       add(Integer.toString(i)); 
      } 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      if(convertView == null){ 
       convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false); 
       ViewHolder holder = new ViewHolder(); 
       holder.header = (TextView) convertView.findViewById(R.id.header); 
       convertView.setTag(holder);    
      } 
      ViewHolder holder = (ViewHolder) convertView.getTag(); 
      holder.header.setText(getItem(position)); 
      return convertView; 
     } 
    } 

    private static class ViewHolder { 
     TextView header; 
     int previousTop = 0; 
    } 
} 
+0

अरे siyamed, यह बहुत उपयोगी है। मेरे मामले में मेरे पास ListView (अभिभावक) के अंदर एक और सूची दृश्य (बच्चा) है। इसलिए जब मैं स्क्रॉलिंग कर रहा हूं तो हेडर ठीक से काम नहीं कर रहा है .... – ashish2py

+0

यदि बच्चे-सूचीदृश्य में कोई डेटा नहीं है, तो यह ठीक से काम करता है .. > नमूना ऐप https://bitbucket.org/ashish2py/instagramheader – ashish2py

+0

मैं इसे आज़माउंगा। धन्यवाद! –

0

यदि आप सूची दृश्य का उपयोग कर रहे हैं तो अपनी सूची आइटम के अंदर 2 विचार हैं। एक हेडर है और दूसरा वास्तव में आइटम है।

प्रारंभ में हेडर व्यू छुपाएं और स्क्रॉल स्थिति में परिवर्तन के रूप में या उपयोगकर्ता आपकी सूची आइटम को छूता है शीर्षलेख की दृश्यता बदलता है।

0

आपके सेटकंटिव्यूव्यू के बाद नीचे दिए गए कोड की तरह कुछ करें।

ListView list = getListView(); 
    View footer = getLayoutInflater().inflate(R.layout.footerlayout, list, false); 
    View header = getLayoutInflater().inflate(R.layout.headerlayout, list, false); 
    list.addHeaderView(header); 
    list.addFooterView(footer); 
1

मैं Siyamed के सवाल का एक छोटा सा सुधारा है ताकि हैडर जब दृश्य उदाहरण के लिए दोबारा बनाई है अगर सूचीदृश्य मद में एक बिटमैप बदल गया है हटे नहीं हैं।

अंतिम स्थिति के सापेक्ष निर्देशांक का उपयोग करने के बजाय मैं दृश्य के शीर्ष के सापेक्ष निर्देशांक का उपयोग करता हूं और ऑफ़सेट के बजाय पैडिंग का उपयोग करता हूं।

@Override 
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 

    for(int i=0; i < list.getChildCount(); i++){ 
     View child = list.getChildAt(i); 
     ViewHolder holder = (ViewHolder) child.getTag(); 

     if(i == 0){ 
      try { 
       boolean isAtBottom = child.getHeight() <= holder.movingHeader.getBottom(); 
       if(!(isAtBottom)){ 
        if (child.getTop() >= 0){} 
        else if (child.getHeight() - movingHeader.getHeight() - 1 > -child.getTop()) 
        { 
         holder.movingHeader.setPadding(0, -child.getTop(), 0, 0); 
         holder.movingHeader.invalidate(); 
        } 
        else { 
         holder.movingHeader.setPadding(0, child.getHeight() - movingHeader.getHeight(), 0, 0); 
         holder.movingHeader.invalidate(); 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
     else if (holder.movingHeader.getPaddingTop() != 0) 
     { 
      holder.movingHeader.setPadding(0, 0, 0, 0); 
      holder.movingHeader.invalidate(); 
     } 
    } 
} 
-1

मैं जानता हूँ कि इस सवाल का एक छोटा सा पुराना है, लेकिन StickyListHeaders पुस्तकालय है, जो अनुभाग हेडर के निर्माण के सार संक्षेप की एक बहुत अच्छा काम करता है खोजने के लिए कामयाब रहे।

https://github.com/emilsjolander/StickyListHeaders

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