एंड्रॉइड लिस्टव्यू को रिफ्रेश कैसे करें?


436

ListViewडायनामिक डेटा जोड़ने / हटाने के बाद एंड्रॉइड को रिफ्रेश कैसे करें ?


3
यदि अन्य समाधान काम नहीं करते हैं, तो ताज़ा करें प्रयास करें। रंगमंच की सामग्री के लिए stackoverflow.com/questions/5186359/...
एडविन इवांस

आपकी मदद कर सकते हैं, stackoverflow.com/a/17333384/596555
उबला हुआ पानी

यहाँ एक उदाहरण tutorialkart.com/kotlin-android/… आपकी मदद कर सकता है।
मल्लिकार्जुन एम

जवाबों:


530

उस एडॉप्टर में डेटा संशोधित करने के बाद एक बार notifyDataSetChanged()अपने Adapterऑब्जेक्ट पर कॉल करें ।

इस Google I / O वीडियो को कैसे / कब कॉल करना है notifyDataSetChanged(), इस पर कुछ अतिरिक्त बारीकियों को देखा जा सकता है ।


24
आपको इसे यूआई थ्रेड पर चलाना चाहिए। UI थ्रेड के भीतर एक हैंडलर बनाएं और फिर इसे रन करने योग्य बनाएं
Kirill Kulakov

11
एक बार फिर से: InformDataSetChanged () कम से कम उन अभ्यास पद्धतियों के लिए काम नहीं करता है, जो पुनर्संरचित हैं (पढ़ा नहीं गया है)। यदि आप सूची, कर्सर एडाप्टर और सामग्री प्रदाता का उपयोग करते हैं, तो आप लाइनों के साथ कुछ आज़मा सकते हैं: gettLoaderManager ()। पुनः आरंभ करें ()। देखें: stackoverflow.com/a/19657500/1087411 मैं InformDataSetChanged () पर कम से कम कुछ दस्तावेज देखना चाहूंगा। एंड्रॉइड में बहुत कुछ ब्लैक बॉक्स परीक्षण के लिए छोड़ दिया गया है।
एंडरसन

अगर InformDataSetChanged काम नहीं करता है, तो आप वही हैं जो इसे गलत कर रहे हैं
zdarsky.peter

4
अधिसूचितडेटाचेंज हमेशा काम नहीं करता है। मुझे यकीन नहीं है कि यह विवाद में है। कभी-कभी आपको पुराने विचारों को हटाने के लिए listView.setAdapter (एडॉप्टर) पर कॉल करना होगा। इसे भी देखें: stackoverflow.com/a/16261588/153275

1
मैं कभी भी काम नहीं कर पाया। मैं स्पष्ट रूप से देख सकता हूं कि एडेप्टर को मैं जो संग्रह करता हूं, वह बदल गया है (तत्व हटा दिए गए थे), लेकिन InformDataSetChanged ने कभी कुछ नहीं किया है। निश्चित नहीं है कि क्या यह विधि अभी टूटी है?
byemute

204

इसके अलावा आप इसका उपयोग कर सकते हैं:

myListView.invalidateViews();

22
यह सही उत्तर है यदि किसी को केवल दृश्य को पुनः लोड करने की आवश्यकता है। उदाहरण के लिए, उपयोगकर्ता लॉगिन होने के बाद सूची के प्रत्येक दृश्य के भीतर अधिक जानकारी या विकल्पों को उजागर करने की आवश्यकता होती है। मुझे यही करना था, इसलिए अप-वोट दिया। यदि अंतर्निहित डेटा बदल जाता है, तो शायद InformDataSetChanged () का उपयोग करना बेहतर होगा।
SBerg413

invalidateViews()स्रोत कोड में वास्तव में सेट करता है mDataChanged = true;तो मुझे यकीन नहीं है कि अगर यह बेहतर प्रदर्शन की तुलना मेंnotifyDataSetChanged()
vovahost

तुमने मेरा दिन बचाया, यार!
ऑस्करको

आप एक प्रकार की सूची ले सकते हैं जो "अवलोकन योग्य सूची" है, नोटिफ़ाइडसेट को बदलने की आवश्यकता नहीं है
प्रिया

153

सभी की उपेक्षा करें invalidate(), invalidateViews(), requestLayout(), ... इस सवाल का जवाब।

सही काम करने के लिए (और सौभाग्य से सही उत्तर के रूप में भी चिह्नित किया गया है) अपने एडाप्टर पर कॉल notifyDataSetChanged()करना है

समस्या निवारण

यदि कॉलिंग notifyDataSetChanged()सभी लेआउट तरीकों से काम नहीं करती है तो भी मदद नहीं करेगी। यकीन मानिए मुझे ListViewठीक से अपडेट किया गया था। यदि आप उस अंतर को खोजने में विफल रहते हैं जो आपको जांचने की आवश्यकता है कि आपके एडेप्टर में डेटा कहां से आता है।

यदि यह सिर्फ एक संग्रह है जिसे आप मेमोरी चेक में रख रहे हैं जिसे आपने कॉल करने से पहले आइटम से वास्तव में हटा दिया है या संग्रह में जोड़ दिया है notifyDataSetChanged()

यदि आप एक डेटाबेस या सेवा बैकएंड के साथ काम कर रहे हैं, तो आपको कॉल करने से पहले सूचना पुनः प्राप्त करने के लिए विधि (या मेमोरी डेटा में हेरफेर) को कॉल करना होगा notifyDataSetChanged()

बात यह है notifyDataSetChangedकि अगर डाटासेट बदल गया है तो यह केवल काम करता है। तो यह देखने की जगह है कि क्या आपको बदलाव नहीं आता है। जरूरत पड़ने पर डिबग करें।

ArrayAdapter बनाम BaseAdapter

मैंने पाया कि एडेप्टर के साथ काम करने से आप संग्रह का प्रबंधन कर सकते हैं, जैसे बेस एडेप्टर बेहतर काम करता है। ArrayAdapter जैसे कुछ एडेप्टर पहले से ही अपने संग्रह को प्रबंधित करते हैं, जिससे अपडेट के लिए उचित संग्रह प्राप्त करना कठिन हो जाता है। यह वास्तव में ज्यादातर मामलों में कठिनाई की एक अनावश्यक अतिरिक्त परत है।

यूआई थ्रेड

यह सच है कि यह यूआई थ्रेड से बुलाया जाना है। अन्य उत्तरों के उदाहरण हैं कि इसे कैसे प्राप्त किया जाए। हालाँकि यह केवल तभी आवश्यक है जब आप UI थ्रेड के बाहर से इस जानकारी पर काम कर रहे हों। यह सेवा या गैर UI थ्रेड से है। साधारण मामलों में आप एक बटन क्लिक या किसी अन्य गतिविधि / टुकड़े से अपने डेटा को अपडेट कर रहे होंगे। यूआई थ्रेड के भीतर अभी भी। हमेशा पॉप करने की आवश्यकता नहीं है जो runOnUiTrhead में चलता है।

त्वरित उदाहरण परियोजना

Https://github.com/hanscappelle/so-2250770.git पर पाया जा सकता है । बस क्लोन करें और Android Studio (gradle) में प्रोजेक्ट खोलें। इस परियोजना में ListViewसभी यादृच्छिक डेटा के साथ एक MainAcitivity बिल्डिंग है । यह सूची एक्शन मेनू का उपयोग करके ताज़ा की जा सकती है।

इस उदाहरण के लिए मैंने जो एडॉप्टर कार्यान्वयन तैयार किया है वह मॉडलऑब्जेक्ट डेटा संग्रह को उजागर करता है

public class MyListAdapter extends BaseAdapter {

    /**
     * this is our own collection of data, can be anything we 
     * want it to be as long as we get the abstract methods 
     * implemented using this data and work on this data 
     * (see getter) you should be fine
     */
    private List<ModelObject> mData;

    /**
     * our ctor for this adapter, we'll accept all the things 
     * we need here
     *
     * @param mData
     */
    public MyListAdapter(final Context context, final List<ModelObject> mData) {
        this.mData = mData;
        this.mContext = context;
    }

    public List<ModelObject> getData() {
        return mData;
    }

    // implement all abstract methods here
}

MainActivity से कोड

public class MainActivity extends Activity {

    private MyListAdapter mAdapter;

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

        ListView list = (ListView) findViewById(R.id.list);

        // create some dummy data here
        List<ModelObject> objects = getRandomData();
        // and put it into an adapter for the list
        mAdapter = new MyListAdapter(this, objects);
        list.setAdapter(mAdapter);

        // mAdapter is available in the helper methods below and the 
        // data will be updated based on action menu interactions

        // you could also keep the reference to the android ListView 
        // object instead and use the {@link ListView#getAdapter()} 
        // method instead. However you would have to cast that adapter 
        // to your own instance every time
    }

    /**
     * helper to show what happens when all data is new
     */
    private void reloadAllData(){
        // get new modified random data
        List<ModelObject> objects = getRandomData();
        // update data in our adapter
        mAdapter.getData().clear();
        mAdapter.getData().addAll(objects);
        // fire the event
        mAdapter.notifyDataSetChanged();
    }

    /**
     * helper to show how only changing properties of data 
     * elements also works
     */
    private void scrambleChecked(){
        Random random = new Random();
        // update data in our adapter, iterate all objects and 
        // resetting the checked option
        for( ModelObject mo : mAdapter.getData()) {
            mo.setChecked(random.nextBoolean());
        }
        // fire the event
        mAdapter.notifyDataSetChanged();
    }
}

अधिक जानकारी

Listviews की शक्ति के बारे में एक अच्छा पोस्ट यहाँ पाया जाता है: http://www.vogella.com/articles/AndroidListView/article.html


16
तुम गलत हो। InformDataSetChanged () ने मेरे लिए काम नहीं किया, लेकिन अमान्य दृश्यों () ने इसे सही किया।
बाबे

6
मेरे पास समस्या है जहां सूची में वास्तविक तत्व नहीं बदलते हैं, उदाहरण के लिए तत्वों की समान मात्रा। लेकिन समस्या यह है कि उन्हें जिस तरह से पेश किया जाता है उसे बदलने की जरूरत है। इसका मतलब है कि यूआई बनाने के लिए मेरे एडेप्टर कोड को फिर से चलाने की आवश्यकता है और फिर सूची पंक्तियों में कुछ तत्व को सही ढंग से छिपाएं। सूचनाडॉटसेटचैनड () काम नहीं करता है ...
स्वेन हाइज

9
इस जवाब ने वास्तव में मेरी मदद की। मैं कुछ विशेष कारणों से स्मृति में सरणी रख रहा था। इसे ठीक करने के लिए मैं अब फोन करता हूं adapter.clear(), और adapter.addAll(Array<T>)फोन करने से पहलेnotifyDataSetChanged()
माइकल डीपिलिप्स

2
@hcpl, अगर मुझे अडॉप्टरऑनलाइनस्टिकर में चेकबॉक्स के लिए है तो मुझे कैसे सूचित करना चाहिएडेटडेटैटचैनजेड? अमान्य दृश्य अभी काम कर रहे हैं। कॉल करने के लिए गलत तरीका क्यों अमान्य है?
craned

1
मैं कभी भी काम नहीं कर पाया। मैं स्पष्ट रूप से देख सकता हूं कि एडेप्टर को मैं जो संग्रह करता हूं, वह बदल गया है (तत्व हटा दिए गए थे), लेकिन InformDataSetChanged ने कभी कुछ नहीं किया है। निश्चित नहीं है कि क्या यह विधि अभी टूटी है?
byemute

42

जब चाहे तब कॉल करें:

runOnUiThread(run);

OnCreate(), आपने अपना रनवेबल धागा सेट किया:

run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};

1
मेरे मामले में भी काम करना, जहां मुझे टीसीपी कनेक्शन (एक "नॉनयूआई" थ्रेड) से आने वाले डेटा के आधार पर एक सूची को अपडेट करने की आवश्यकता है। सूची को फिर से व्यवस्थित करने का एकमात्र तरीका ArrayList के सभी तत्वों को स्पष्ट और पुनः जोड़ना था। वैसे भी, यदि आप पहले से ही UI थ्रेड में हैं, तो आपको runOnUiThread()फ़ंक्शन के माध्यम से कोड को कॉल करने की आवश्यकता नहीं है ।
आंद्रे

धन्यवाद! इससे मेरा काम बनता है। सभी लोग जो इसे एक टुकड़े से चलाना चाहते हैं, के लिए आपको getActivity () का उपयोग करना चाहिए। runOnUiThread (नया Runnable ... यह सुनिश्चित करने के लिए कि कोड यूआई थ्रेड पर चलाया जाता है
कोडिंगपस

मुझे इसका उद्देश्य नहीं दिखता है run = new Runnable()और मैंने अपने कार्य को एक public void refreshUIThread()तरीका दिया है run()जो आपके तरीके को मॉडल करता है (जो काम करता है, भी)।
T.Woody

11

मुझे अपनी सूची के डायनामिक रिफ्रेश के साथ कुछ समस्याएं मिलीं।

अपने एडेप्टर पर InformDataSetChanged () को कॉल करें।

कुछ अतिरिक्त बारीकियों पर कैसे / कब कॉल करें InformDataSetChanged () को इस Google I / O वीडियो में देखा जा सकता है।

अपने मामले में नोटिफ़ाइंडसेटसेटेड () ने ठीक से काम नहीं किया [मैंने नोटिडेटडैटसचेंज को अपनी कक्षा से बुलाया]। बस उस स्थिति में जब मैंने चल गतिविधि (थ्रेड) में सूची दृश्य संपादित किया। क्रिस्टोफर के लिए उस वीडियो धन्यवाद ने अंतिम संकेत दिया।

अपनी दूसरी कक्षा में मैंने प्रयोग किया

Runnable run = new Runnable(){
     public void run(){
         contactsActivity.update();
     }
};
contactsActivity.runOnUiThread(run);

मेरी गतिविधि से अद्यतन () को प्राप्त करने के लिए। इस अद्यतन में शामिल हैं

myAdapter.notifyDataSetChanged();

दृश्य को ताज़ा करने के लिए एडाप्टर को बताने के लिए। जहां तक ​​मैं कह सकता हूं, ठीक काम किया।



5

यदि आप अभी भी ListView Refreshment से संतुष्ट नहीं हैं, तो आप इस स्निपेट को देख सकते हैं, यह DB से listView को लोड करने के लिए है, वास्तव में आपको क्या करना है, बस ListView को फिर से लोड करना है, किसी भी CRUD ऑपरेशन को करने के बाद इसका सबसे अच्छा तरीका नहीं है। कोड, लेकिन यह इच्छा के रूप में सूची दृश्य ताज़ा करेगा।

यह मेरे लिए काम करता है .... अगर आप बेहतर समाधान पाते हैं, तो कृपया साझा करें ...

.......
......
अपने CRUD संचालन करो ..
......
.....
DBAdapter.open ();
DBAdapter.insert_into_SingleList ();
// उस DB_results को लाएं और उसकी सामग्री के रूप में सूची में जोड़ें ...।
                                            ls2.setAdapter (नया एरियर एडेप्टर (DynTABSample.this),
    android.R.layout.simple_list_item_1, DBAdcape.DB_ListView));
                                            DBAdapter.close ();

2

इस पोस्ट में लोगों द्वारा प्रस्तावित समाधान आपके डिवाइस के एंड्रॉइड संस्करण पर मुख्य रूप से काम करता है या नहीं। AddAll पद्धति का उपयोग करने के लिए उदाहरण के लिए आपको अपने Android डिवाइस में android: minSdkVersion = "10" डालना होगा।

सभी उपकरणों के लिए इस प्रश्न को हल करने के लिए मैंने अपने एडॉप्टर में स्वयं की विधि बनाई है और ArrayAdapter से इनहेरिट और रिमूव मेथड के अंदर उपयोग करें जो आपको समस्याओं के बिना डेटा अपडेट करते हैं।

मेरा कोड: मेरे अपने डेटा वर्ग का उपयोग कर रहा है ।ResResult, आप अपने खुद के डेटा मॉडल का उपयोग करते हैं।

ResultGpRowAdapter.java

public class ResultGpRowAdapter extends ArrayAdapter<RaceResult> {

    Context context;
    int resource;
    List<RaceResult> data=null;

        public ResultGpRowAdapter(Context context, int resource, List<RaceResult> objects)           {
        super(context, resource, objects);

        this.context = context;
        this.resource = resource;
        this.data = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ........
        }

        //my own method to populate data           
        public void myAddAll(List<RaceResult> items) {

        for (RaceResult item:items){
            super.add(item);
        }
    }

ResultsGp.java

public class ResultsGp extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...........
    ...........
    ListView list = (ListView)findViewById(R.id.resultsGpList); 

    ResultGpRowAdapter adapter = new ResultGpRowAdapter(this,  R.layout.activity_result_gp_row, new ArrayList<RaceResult>()); //Empty data

   list.setAdapter(adapter);

   .... 
   ....
   ....
   //LOAD a ArrayList<RaceResult> with data

   ArrayList<RaceResult> data = new ArrayList<RaceResult>();
   data.add(new RaceResult(....));
   data.add(new RaceResult(....));
   .......

   adapter.myAddAll(data); //Your list will be udpdated!!!

1

यदि आप ताज़ा करते समय अपनी स्क्रॉल स्थिति बनाए रखना चाहते हैं, और आप यह कर सकते हैं:

if (mEventListView.getAdapter() == null) {
    EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
    mEventListView.setAdapter(eventLogAdapter);
} else {
    ((EventLogAdapter)mEventListView.getAdapter()).refill(events);
}

public void refill(List<EventLog> events) {
    mEvents.clear();
    mEvents.addAll(events);
    notifyDataSetChanged();
}

विस्तार से जानकारी के लिए, कृपया Android ListView देखें : ताज़ा करते समय अपनी स्क्रॉल स्थिति बनाए रखें


1

बस myArrayList.remove(position);एक श्रोता के अंदर का उपयोग करें :

  myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override public void onItemClick(AdapterView<?> parent, android.view.View view, int position, long id) {
           myArrayList.remove(position);
           myArrayAdapter.notifyDataSetChanged();
        }
    });

1

आपको उस सूची की एक एकल वस्तु का उपयोग करने की आवश्यकता है, जिसके डेटा को आप फुला रहे हैं ListView। यदि संदर्भ परिवर्तन है, तो notifyDataSetChanged()काम नहीं करता है। जब भी आप सूची दृश्य से तत्वों को हटा रहे हैं, तो उन्हें उस सूची से भी हटा दें जिसे आप उपयोग कर रहे हैं चाहे वह एक ArrayList <> या कुछ और हो तो notifyDataSetChanged()अपने एडेप्टर वर्ग के ऑब्जेक्ट पर कॉल करें ।

तो यहाँ देखें कि मैंने इसे अपने एडॉप्टर में कैसे प्रबंधित किया नीचे देखें

public class CountryCodeListAdapter extends BaseAdapter implements OnItemClickListener{

private Context context;
private ArrayList<CountryDataObject> dObj;
private ViewHolder holder;
private Typeface itemFont;
private int selectedPosition=-1;
private ArrayList<CountryDataObject> completeList;

public CountryCodeListAdapter(Context context, ArrayList<CountryDataObject> dObj) {
    this.context = context;
    this.dObj=dObj;
    completeList=new  ArrayList<CountryDataObject>();
    completeList.addAll(dObj);
    itemFont=Typeface.createFromAsset(context.getAssets(), "CaviarDreams.ttf");
}

@Override
public int getCount() {
    return dObj.size();
}

@Override
public Object getItem(int position) {
    return dObj.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
    if(view==null){
        holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.states_inflator_layout, null);
        holder.textView = ((TextView)view.findViewById(R.id.stateNameInflator));
        holder.checkImg=(ImageView)view.findViewById(R.id.checkBoxState);
        view.setTag(holder);
    }else{
        holder = (ViewHolder) view.getTag();
    }
    holder.textView.setText(dObj.get(position).getCountryName());
    holder.textView.setTypeface(itemFont);

    if(position==selectedPosition)
     {
         holder.checkImg.setImageResource(R.drawable.check);
     }
     else
     {
         holder.checkImg.setImageResource(R.drawable.uncheck);
     }
    return view;
}
private class ViewHolder{
    private TextView textView;
    private ImageView checkImg;
}

public void getFilter(String name) {
    dObj.clear();
    if(!name.equals("")){
    for (CountryDataObject item : completeList) {
        if(item.getCountryName().toLowerCase().startsWith(name.toLowerCase(),0)){
            dObj.add(item);
        }
    }
    }
    else {
        dObj.addAll(completeList);
    }
    selectedPosition=-1;
    notifyDataSetChanged();
    notifyDataSetInvalidated(); 
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    Registration reg=(Registration)context;
    selectedPosition=position;
    reg.setSelectedCountryCode("+"+dObj.get(position).getCountryCode());
    notifyDataSetChanged();
}
}

1
आपके स्पष्टीकरण को रेखांकित किया गया है, लेकिन यह मुझे वास्तव में सरणी सूची संदर्भ के बारे में समझ दे रहा है। धन्यवाद
इब्राहीम पुत्र Prakasa

0

सूची दृश्य से डेटा हटाने के बाद, आपको कॉल करना होगा refreshDrawableState()। यहाँ उदाहरण है:

final DatabaseHelper db = new DatabaseHelper (ActivityName.this);

db.open();

db.deleteContact(arg3);

mListView.refreshDrawableState();

db.close();

और कक्षा deleteContactमें विधि DatabaseHelperकुछ इस तरह दिखाई देगी

public boolean deleteContact(long rowId) {

   return db.delete(TABLE_NAME, BaseColumns._ID + "=" + rowId, null) > 0;

}

0

मैं अपने SimpleAdapter को अद्यतन करने के लिए काम करने के लिए InformDataSetChanged () प्राप्त करने में सक्षम नहीं था, इसलिए इसके बजाय मैंने पहले सभी विचारों को हटाने की कोशिश की, जो removeAllViews () का उपयोग करते हुए मूल लेआउट से जुड़े थे, फिर सूची दृश्य को जोड़ा, और वह काम किया, जिससे मुझे अपडेट करने की अनुमति मिली। यूआई:

LinearLayout results = (LinearLayout)findViewById(R.id.results);
ListView lv = new ListView(this);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter( this, list, R.layout.directory_row, 
                new String[] { "name", "dept" }, new int[] { R.id.name, R.id.dept } );

for (...) { 
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    map.put("dept", dept);
    list.add(map);
}

lv.setAdapter(adapter);
results.removeAllViews();     
results.addView(lv);

0

Sql डेटाबेस में जानकारी बदलने के बाद मेरे लिए कुछ भी सूची दृश्य (विशिष्ट विस्तार योग्य सूची दृश्य होने के लिए) को ताज़ा नहीं किया जा सकता है, इसलिए यदि InformDataSetChanged () मदद नहीं करता है, तो आप पहले अपनी सूची को साफ़ करने का प्रयास कर सकते हैं और फिर उस कॉल के बाद InformDataSetChanged () को जोड़ सकते हैं। उदाहरण के लिए

private List<List<SomeNewArray>> arrayList;
List<SomeNewArray> array1= getArrayList(...);
List<SomeNewArray> array2= getArrayList(...);
arrayList.clear();
arrayList.add(array1);
arrayList.add(array2);
notifyDataSetChanged();

आशा है कि यह आपके लिए समझ में आता है।



0

मैं एक ही था, जब एक टुकड़े में, मैं कुछ समय में स्कैन किए गए BLE उपकरणों के मैक पते के साथ एक ListView (एक एकल TextView में) आबाद करना चाहता था।

मैंने यह क्या किया:

public class Fragment01 extends android.support.v4.app.Fragment implements ...
{
    private ListView                listView;
    private ArrayAdapter<String>    arrayAdapter_string;

...

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    ...
    this.listView= (ListView) super.getActivity().findViewById(R.id.fragment01_listView);
    ...
    this.arrayAdapter_string= new ArrayAdapter<String>(super.getActivity(), R.layout.dispositivo_ble_item, R.id.fragment01_item_textView_titulo);
    this.listView.setAdapter(this.arrayAdapter_string);
}


@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
    ...
    super.getActivity().runOnUiThread(new RefreshListView(device));
}


private class RefreshListView implements Runnable
{
    private BluetoothDevice bluetoothDevice;

    public RefreshListView(BluetoothDevice bluetoothDevice)
    {
        this.bluetoothDevice= bluetoothDevice;
    }

    @Override
    public void run()
    {
        Fragment01.this.arrayAdapter_string.add(new String(bluetoothDevice.toString()));
        Fragment01.this.arrayAdapter_string.notifyDataSetChanged();
    }
}

फिर ListView ने पाया उपकरणों के मैक पते के साथ गतिशील रूप से आबाद करना शुरू कर दिया।


0

मुझे लगता है कि यह इस बात पर निर्भर करता है कि आप रिफ्रेश होने का क्या मतलब है। क्या आपका मतलब है कि जीयूआई डिस्प्ले को रिफ्रेश किया जाना चाहिए, या क्या आपका मतलब है कि बच्चे के विचारों को इस तरह से रिफ्रेश किया जाना चाहिए कि आप प्रोग्रामेटिक रूप से getChildAt (int) को कॉल कर सकें और एडॉप्टर में जो है, उसके अनुरूप व्यू पा सकें।

यदि आप GUI को रिफ्रेश करना चाहते हैं, तो एडाप्टर पर InformDataSetChanged () कॉल करें। अगली रीडायरेक्ट होने पर GUI रिफ्रेश हो जाएगा।

यदि आप getChildAt (int) को कॉल करने में सक्षम होना चाहते हैं और एक दृश्य प्राप्त करें जो दर्शाता है कि एडेप्टर में क्या है, तो लेआउटचिल्ड्रेन () पर कॉल करें। यह एडेप्टर डेटा से बच्चे के दृश्य को फिर से संगठित करने का कारण बनेगा।


0

मेरे पास एक ArrayList था जिसे मैं एक सूची में प्रदर्शित करना चाहता था। ArrayList में mysql के तत्व होते हैं। मैंने ऑनरफ्रेश विधि को ओवरराइड किया और उस पद्धति में मैंने tablelayout.removeAllViews () का उपयोग किया ; और फिर डेटाबेस से डेटा प्राप्त करने के लिए प्रक्रिया को दोहराया। लेकिन इससे पहले कि अपने ArrayList या जो भी डेटा स्ट्रक्चर या फिर नए डेटा को पुराने एक के लिए जोड़ा जाएगा स्पष्ट करना सुनिश्चित करें।


0

यदि आप किसी सेवा से UI सूची को अपडेट करना चाहते हैं, तो एडॉप्टर को अपनी मुख्य गतिविधि में स्थिर बनाएं और यह करें:

@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    

0

आप एंड्रॉयड संबंधी दिशा-निर्देश को देखते हुए तो कर रहे हैं और आप उपयोग कर रहे ContentProvidersसे डेटा प्राप्त करने Databaseऔर आप में यह प्रदर्शित कर रहे हैं ListViewका उपयोग कर CursorLoaderऔर CursorAdapters, तो आप संबंधित डेटा के सभी परिवर्तनों को स्वचालित रूप से ListView में परिलक्षित होगा।

आपके getContext().getContentResolver().notifyChange(uri, null);कर्सर में ContentProviderपरिवर्तन को प्रतिबिंबित करने के लिए पर्याप्त होगा। अतिरिक्त कार्य के लिए किसी की आवश्यकता नहीं है।

लेकिन जब आप इन सभी का उपयोग नहीं कर रहे हैं तो आपको एडेप्टर को तब बदलना होगा जब डेटासेट बदल रहा हो। इसके अलावा, आपको अपने डेटासेट (कहना सूची) को फिर से आबाद / पुनः लोड करने की आवश्यकता है और फिर आपको notifyDataSetChanged()एडॉप्टर पर कॉल करना होगा।

notifyDataSetChanged()वाट्सएप में बदलाव नहीं होने पर काम नहीं करेगा। यहाँ डॉक्स में विधि के ऊपर टिप्पणी है-

/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */

0

मैं केवल नया एडॉप्टर डेटा प्राप्त करके केवल अधिसूचित डेटासेट करने में सक्षम था, फिर सूची दृश्य के लिए एडेप्टर को रीसेट करना, फिर कॉल करना जैसे:

    expandableAdapter = baseFragmentParent.setupEXLVAdapter();
    baseFragmentParent.setAdapter(expandableAdapter);
    expandableAdapter.notifyDataSetChanged(); 

0

अन्य विकल्प पर onWindowFocusChangedविधि है, लेकिन यकीन है कि इसके संवेदनशील और कुछ अतिरिक्त कोडिंग की जरूरत है जिसके लिए रुचि है

 override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)

       // some controls needed
        programList = usersDBHelper.readProgram(model.title!!)
        notesAdapter = DailyAdapter(this, programList)
        notesAdapter.notifyDataSetChanged()
        listview_act_daily.adapter = notesAdapter
    }

0

विचार करें कि आपने अपने एडॉप्टर को एक सूची दी है।
उपयोग:

list.getAdapter().notifyDataSetChanged()

अपनी सूची अपडेट करने के लिए।


0

अगर मैंने यहां अपने परिदृश्य के बारे में बात की है, तो उपरोक्त उत्तर में से कोई भी काम नहीं करेगा क्योंकि मेरे पास गतिविधि थी जो डिलीट बटन के साथ db मानों की सूची दिखाती है और जब एक डिलीट बटन दबाया जाता है, तो मैं उस आइटम को सूची से हटाना चाहता था।

ठंडी बात यह थी, मैंने रिसाइक्लर व्यू का उपयोग नहीं किया था लेकिन एक साधारण सूची दृश्य और उस सूची को एडेप्टर वर्ग में आरंभीकृत किया गया था। इसलिए, कॉलिंग notifyDataSetChanged()एडॉप्टर क्लास के अंदर और यहां तक ​​कि एक्टिविटी क्लास में भी नहीं होगी जहां एडॉप्टर ऑब्जेक्ट को इनिशियलाइज़ किया गया है क्योंकि एडेप्टर क्लास में डिलीट मेथड था।

तो, समाधान एडाप्टर क्लास getViewविधि में एडाप्टर से ऑब्जेक्ट को हटाने के लिए था (केवल उस विशिष्ट ऑब्जेक्ट को हटाने के लिए लेकिन अगर आप सभी को हटाना चाहते हैं, तो कॉल करें clear())।

कुछ विचार पाने के लिए, मेरा कोड क्या था,

public class WordAdapter extends ArrayAdapter<Word> {
  Context context;

  public WordAdapter(Activity context, ArrayList<Word> words) {}
    //.......

    @NonNull
    @Override
    public View getView(final int position, View convertView, ViewGroup group) {
      //.......
     ImageButton deleteBt = listItemView.findViewById(R.id.word_delete_bt);
     deleteBt.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             if (vocabDb.deleteWord(currentWord.id)) {
                //.....
             } else{
                //.....
             }
             remove(getItem(position)); // <---- here is the trick ---<
             //clear() // if you want to clear everything
         }
    });
 //....

नोट: यहां remove()और getItem()विधियां एडेप्टर वर्ग से विरासत में मिली हैं।

  • remove() - क्लिक किए जाने वाले विशिष्ट आइटम को हटाने के लिए
  • getItem(position) - आइटम को प्राप्त करना है (यहां, मेरा वर्ड ऑब्जेक्ट जो मैंने सूची में जोड़ा है) पर क्लिक की गई स्थिति से।

इस तरह से मैंने एक्टिविटी क्लास में लिस्टव्यू के लिए एडॉप्टर सेट किया,

    ArrayList<Word> wordList = new ArrayList();
    WordAdapter adapter = new WordAdapter(this, wordList);

    ListView list_view = (ListView) findViewById(R.id.activity_view_words);
    list_view.setAdapter(adapter);

-1

सबसे आसान बस एक नया एडपर बनाना और पुराने को छोड़ना है:

myListView.setAdapter(new MyListAdapter(...));

इसके सेवन से याददाश्त बढ़ती है।
खिलाड़ी 1

कचरा एकत्र किया जाएगा
user1712200
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.