2010-01-23 19 views
72

ListView की एक पंक्ति के लिए डेटा प्राप्त करने के बाद, मैं उस पंक्ति को अपडेट करना चाहता हूं।एंड्रॉइड लिस्ट व्यू रीफ्रेश सिंगल रो

वर्तमान में मैं notifyDataSetChanged(); का उपयोग कर रहा हूं लेकिन इससे View बहुत धीरे-धीरे प्रतिक्रिया करता है। क्या कोई अन्य समाधान है?

उत्तर

29

एक विकल्प सीधे ListView में हेरफेर करना है। सबसे पहले जांचें कि अद्यतन पंक्ति का सूचकांक getFirstVisiblePosition() और getLastVisiblePosition() के बीच है, तो ये दो आपको स्क्रीन पर दिखाई देने वाले एडाप्टर में पहली और अंतिम स्थिति देते हैं। फिर आप के साथ पंक्ति View प्राप्त कर सकते हैं और इसे बदल सकते हैं।

+3

धन्यवाद। अगर मैं ** ** ** ** ** के वर्तमान लेआउट को संपादित कर रहा हूं तो यह काम करेगा। लेकिन क्या मैं ** पूरी तरह ** (एक अलग एक्सएमएल बढ़ा-चढ़ाकर द्वारा) लेआउट बदलना चाहते हैं? अगर मैं एडाप्टर पर 'newview (...)' कहते हैं, यह मुझे जो तथापि 'listView' में डाल नहीं है एक अलग दृष्टिकोण देता है। – hadi

+1

@hadi आपको यह उत्तर पर एक नज़र रखना चाहिए: http://stackoverflow.com/a/11568271/858626 –

6

निम्नलिखित कोड मेरे लिए काम किया। GetChild() को कॉल करते समय नोट करें, इसके बाद से आप सूची में पहले आइटम से ऑफ़सेट करना होगा।

int iFirst = getFirstVisiblePosition(); 
int iLast = getLastVisiblePosition(); 

if (indexToChange >= numberOfRowsInSection()) { 
    Log.i("MyApp", "Invalid index. Row Count = " + numberOfRowsInSection()); 
} 
else {  
    if ((index >= iFirst) && (index <= iLast)) { 
     // get the view at the position being updated - need to adjust index based on first in the list 
     View vw = getChildAt(sysvar_index - iFirst); 
     if (null != vw) { 
      // get the text view for the view 
      TextView tv = (TextView) vw.findViewById(com.android.myapp.R.id.scrollingListRowTextView); 
      if (tv != null) { 
       // update the text, invalidation seems to be automatic 
       tv.setText("Item = " + myAppGetItem(index) + ". Index = " + index + ". First = " + iFirst + ". Last = " + iLast); 
      } 
     } 
    } 
} 
87

रोमेन लड़का explained a while backGoogle I/O session, केवल एक सूची दृश्य में एक दृश्य को अपडेट करें सबसे कारगर तरीका दौरान निम्नलिखित की तरह कुछ (यह एक अद्यतन पूरे दृश्य डेटा) है के रूप में:

ListView list = getListView(); 
int start = list.getFirstVisiblePosition(); 
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++) 
    if(target==list.getItemAtPosition(i)){ 
     View view = list.getChildAt(i-start); 
     list.getAdapter().getView(i, view, list); 
     break; 
    } 

target मानते हैं कि एडाप्टर का एक आइटम है।

इस कोड ListView पुनः प्राप्त है, तो वर्तमान में दिखाए गए दृश्य ब्राउज़ करें, target आइटम आप प्रत्येक के साथ दृश्य आइटम प्रदर्शित करने के लिए देख रहे हैं की तुलना करें और यदि आपका लक्ष्य उन लोगों के बीच है, संलग्न दृश्य प्राप्त और उस पर अनुकूलक getView निष्पादित प्रदर्शन को रीफ्रेश करने के लिए देखें।

एक तरफ ध्यान दें invalidate के रूप में की तरह कुछ लोगों को उम्मीद काम नहीं करता है और getView की तरह दृश्य रीफ़्रेश नहीं होगा करता है, notifyDataSetChanged पूरी सूची के पुनर्निर्माण और हर प्रदर्शित किया मदों के लिए getview और invalidateViews बुला भी एक गुच्छा को प्रभावित करेगा खत्म हो जाएगा।

एक आखिरी बात यह है कि अगर उसे केवल पंक्ति दृश्य के बच्चे को बदलने की जरूरत है और getView जैसी पूरी पंक्ति नहीं है तो कोई अतिरिक्त प्रदर्शन भी प्राप्त कर सकता है। उस मामले में, निम्नलिखित कोड (एक TextView पाठ बदलने के लिए उदाहरण) list.getAdapter().getView(i, view, list); की जगह ले सकता:

((TextView)view.findViewById(R.id.myid)).setText("some new text"); 

कोड में हम पर भरोसा है।

+15

आप शायद सिर्फ नकल के अपने अन्य जवाब http://stackoverflow.com/a/9987616/1026132 लिंक करना चाहिए बजाय और यहाँ पेस्टिंग। इससे एसओ में डुप्लिकेट सामग्री की मात्रा को कम करने में मदद मिलेगी। –

+2

विभिन्न दृश्य प्रकार के साथ इसे कैसे कार्यान्वित करें? जवाब में "गूगल आई/ओ सत्र" के लिए – Zyoo

+1

लिंक मर चुका है। – Pang

26

यह सरल तरीका मेरे लिए अच्छी तरह से काम, और आप केवल देखने के ahold पाने के लिए स्थिति सूचकांक जानने की जरूरत:,

// mListView is an instance variable 

private void updateItemAtPosition(int position) { 
    int visiblePosition = mListView.getFirstVisiblePosition(); 
    View view = mListView.getChildAt(position - visiblePosition); 
    mListView.getAdapter().getView(position, view, mListView); 
} 
+2

वर्क्स एक आकर्षण की तरह, +1 – Rutger

+0

मैं कि अद्यतन मूल्यों भेज देंगे एक और पेज detailview यदि उपयोगकर्ता विवरण है कि पर परिवर्तन पेज वापस अपडेट करने का तरीका कृपया सूची – Harsha

2

एक और भी बहुत कुछ कुशल बात आप कर सकते हैं नहीं है अगर यह फिट बैठता है अपने उपयोग-मामला है।

जाएगा

आप राज्य को बदल रहे हैं और किसी भी तरह उचित कॉल कर सकते हैं (स्थिति जानने के द्वारा) यदि mListView.getAdapter().getView() यह सबसे सभी के कुशल।

मैं अपने ListAdapter.getView() कक्षा में अज्ञात भीतरी कक्षा बनाकर इसे करने का एक आसान तरीका प्रदर्शित कर सकता हूं।इस उदाहरण में मैं एक TextView एक पाठ 'नई' दिखाए जा रहे हैं और उस दृश्य जब सूची आइटम क्लिक किया जाता है GONE पर सेट है:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    // assign the view we are converting to a local variable 
    View view = convertView; 

    Object quotation = getItem(position); 
    // first check to see if the view is null. if so, we have to inflate it. 
    if (view == null) 
     view = mInflater.inflate(R.layout.list_item_quotation, parent, false); 

    final TextView newTextView = (TextView) view.findViewById(R.id.newTextView); 

    view.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (mCallbacks != null) 
       mCallbacks.onItemSelected(quotation.id); 
      if (!quotation.isRead()) { 
       servicesSingleton.setQuotationStatusReadRequest(quotation.id); 
       quotation.setStatusRead(); 
       newTextView.setVisibility(View.GONE); 
      } 
     } 
    }); 

    if(quotation.isRead()) 
     newTextView.setVisibility(View.GONE); 
    else 
     newTextView.setVisibility(View.VISIBLE); 

    return view; 
} 

ढांचे स्वचालित रूप से सही position का उपयोग करता है और आप इसे प्राप्त करने में कठिनाई के बारे में चिंता करने की ज़रूरत है getView पर कॉल करने से पहले।

-1

बस रिकार्ड के लिए, किसी को भी 'देखें दृश्य' ओवरराइड विधि पर विचार किया?

public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

        //Update the selected item 
        ((TextView)view.findViewById(R.id.cardText2)).setText("done!"); 

       } 
+0

सवाल यह है कि किसी भी पर ListView में एक ही पंक्ति ताज़ा करने के लिए था पल। onItemClick केवल उपयोगकर्ताओं द्वारा किसी आइटम को क्लिक कहा जाता है और इतने पर्याप्त नहीं है – Thys

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