简体   繁体   中英

Updating ListView from another Activity

Activity 1: Contains ListView.

Acitivity 2: Contains SeekBar that changes a SharedPreferences variable which used by the ListView. After changing the SeekBar and returning to Activity 1, the ListView need to be updated and refreshed.

After I update the SeekBar at Activity 2 I use the following code to return to Activity 1:

        toolbar.setNavigationIcon(R.drawable.ic_arrow_forward_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//I need to update the list here, There may be a new data!
                onBackPressed();

            }
        });

my Activity 1 remains the same ListView unupdated.

I can't find a good way to refresh my list in Activity 1 after changing the Seekbar, since the adapter available only at Activity 1. I was trying to pass it as intent, but I noticed it's impossible to pass adapters as extras.

Any help?

Code I use to update the ListView in Activity 1:

mainListView = (ListView) findViewById(R.id.main_listview);
                    // 5. Set this activity to react to list items being pressed
                    //mainListView.setOnItemClickListener(MainActivity.this);
                    // 10. Create a JSONAdapter for the ListView
                    mJSONAdapter = new JSONAdapter(MainActivity.this, getLayoutInflater());
                    // Set the ListView to use the ArrayAdapter
                    mainListView.setAdapter(mJSONAdapter);

Logcat error after trying Udi's solution:

08-27 12:58:29.400    1595-1595/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: il.co.test.test, PID: 1595
    java.lang.RuntimeException: Unable to resume activity {il.co.test.test/il.co.test.test.MainActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2788)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2817)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at il.co.test.test.MainActivity.onResume(MainActivity.java:334)
            at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1192)
            at android.app.Activity.performResume(Activity.java:5310)
            at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2778)
            at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2817)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2250)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5017)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
            at dalvik.system.NativeStart.main(Native Method)

EDIT 2: FULL CODE HOW I UPDATE MY LIST - AFTER GPS TRACKING. Placed in MainActivity.java. Called in TabFragment1.java (code below)

public void getUpdates()
{
    // Access the device's key-value storage
    mSharedPreferences = getSharedPreferences(PREFS, MODE_PRIVATE);
    searchDistance = mSharedPreferences.getInt(PREF_DISTANCE, 0);
    if (searchDistance == 0)
        searchDistance = DEFAULT_SEARCH_DISTANCE;

        gpsDialog = new ProgressDialog(this);
        gpsDialog.setMessage("Checking your location..");
        gpsDialog.setCancelable(false);

        gpsDialog.show();

        MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
            @Override
            public void gotLocation(Location location) {
                gpsDialog.dismiss();
                //If we find a location, We will go to the list layout.
                //setContentView(R.layout.fb_list);
                // 4. Access the ListView
                mainListView = (ListView) findViewById(R.id.main_listview);
                // 5. Set this activity to react to list items being pressed
                //mainListView.setOnItemClickListener(MainActivity.this);
                // 10. Create a JSONAdapter for the ListView
                mJSONAdapter = new JSONAdapter(MainActivity.this, getLayoutInflater());
                // Set the ListView to use the ArrayAdapter
                mainListView.setAdapter(mJSONAdapter);
                double lat = location.getLatitude();
                double lon = location.getLongitude();
                query(lat, lon, searchDistance);
            }
        };
        MyLocation myLocation = new MyLocation(this);
        myLocation.getLocation(this, locationResult);
}

Calling this method from my Fragment:

    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    final View v = inflater.inflate(R.layout.fb_list, container, false);
    MainActivity king = (MainActivity)getActivity();
    king.getUpdates();
    return v;
}

When I add this:

@Override
protected void onResume() {
    super.onResume();

    //if the data has changed
    mJSONAdapter.notifyDataSetChanged();
}

app crashes becuase it can't find the json adapter (since it's initalized only after gps location)

If the adapater's backing data is changed, you should notify the adapter. In your scenario what you might consider is adding a check in onResume method if the data has changed, and if it did change notify the adapter:

@Override
protected void onResume() {
    super.onResume();

    //if the data has changed
    mJSONAdapter.notifyDataSetChanged(); 
}

This is just a Issue of Null Pinter Exception. But the basic steps are as follows

Create the Adapter and keep it. Keep a reference to the List of items that you pass into the Adapter also, When you come from the Activity 2 As Udi I you can clear the list of Items and Add the new items to it (Do not add the items as a new List, If you do that, you have to reinstantiate the Adapter again and reset the Adapter). And then call the notifyDataSetChanged() on the adapter.

EDIT1:

I suggest you to look into the Activity life-cycle more and communication between Activity and Fragment. I assume that you toggle fragments (TabFragment1) inside Activity 1.

I do not recommend this, But you can try this,

@Override
protected void onRestart() {
    super.onRestart();
    getUpdates();
    mainListView.setAdapter(mJSONAdapter);
}

But you have to make sure that,

// 10. Create a JSONAdapter for the ListView
                mJSONAdapter = new JSONAdapter(MainActivity.this, getLayoutInflater());

this mJsonAdapter is not null.

I solved it by replacing this:

        toolbar.setNavigationIcon(R.drawable.ic_arrow_forward_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//I need to update the list here, There may be a new data!
                onBackPressed();

            }
        });

with this:

toolbar.setNavigationIcon(R.drawable.ic_arrow_forward_white_24dp);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent refresh = new Intent(Settings.this, MainActivity.class);
                    Settings.this.startActivity(refresh);
                }
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM