user3075478
user3075478

Reputation: 137

Repeatedly update a list in the ListFragment

I'm using the Estimote SDK for Android. I'm trying to change the provided code on the official site. I want to show the list of the detected beacons in a ListFragment (with some information for each Beacon).

In my main Activity i start all the necessary (service, listeners..), and in particular i have this onCreate(...) method:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    beaconManager.setRangingListener(new BeaconManager.RangingListener() {
        @Override
        public void onBeaconsDiscovered(Region region, List<Beacon> beacons) {
           // update the list of the beacons in the ListFragment in some way
        }
    });
}

If i understood correctly, this method is called continuosly every fixed time.

This is the code of the ListFragment:

public class DiscoveredBeacons extends ListFragment {

    private List<Beacon> beacons = new ArrayList<Beacon>();
    private Beacon beacon;
    private View mContentView = null;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        this.setListAdapter(new MyListAdapter(getActivity(), R.layout.beacon_row, beacons));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,    Bundle savedInstanceState) {
        mContentView = inflater.inflate(R.layout.beacons_list, null);
        return mContentView;
    }

    // this does not work if i call it from the main Activity
    public void updateList(List<Beacon> beacons) {
        beacons.clear();
        beacons.addAll(beacons);
        ((MyListAdapter) getListAdapter()).notifyDataSetChanged();
    }

    private class MyListAdapter extends ArrayAdapter<Beacon> {

        private List<Beacon> items;

        public MyListAdapter(Context context, int textViewResourceId,
                               List<Beacon> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                LayoutInflater vi = (LayoutInflater)  getActivity().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
                v = vi.inflate(R.layout.beacon_row, null);
            }
            Beacon beacon = items.get(position);
            if (beacon != null) {
                TextView number = (TextView) v.findViewById(R.id.number);
                TextView rssi = (TextView) v.findViewById(R.id.rssi);
                TextView power = (TextView) v.findViewById(R.id.power);
                TextView distance = (TextView) v.findViewById(R.id.distance);
                if(number != null) {
                    number.setText("Beacon number " + (position + 1));
                }
                if (rssi != null) {
                    rssi.setText("rssi: " + beacon.getRssi()); // int
                }
                if (power != null) {
                    power.setText("power: " + beacon.getMeasuredPower()); // int
                }
                if(distance != null) {
                    distance.setText("distance: " + Utils.computeAccuracy(beacon));
                }
            }
            return v;
        }
    }
}

As you can see, i tried to put a public method in the ListFragment, and call it the listener inside the onCreate, but this doesn't work. In particular i get an exception:

04-01 20:14:04.029 18052-18052/it.loris.beaconsdetector E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: it.loris.beaconsdetector, PID: 18052 java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.clear(Collections.java:936) at it.loris.beaconsdetector.DiscoveredBeacons.updateList(DiscoveredBeacons.java:40) at it.loris.beaconsdetector.BeaconsDetector$1.onBeaconsDiscovered(BeaconsDetector.java:41) at com.estimote.sdk.BeaconManager$IncomingHandler.handleMessage(BeaconManager.java:479) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5274) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)

Thank you for your help.

Upvotes: 1

Views: 278

Answers (2)

Adarsh
Adarsh

Reputation: 827

Try adding this to getView()

if (convertView == null) {
            LayoutInflater vi = (LayoutInflater)  getActivity().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.beacon_row, null);
        } else { v = convertView; }

Upvotes: 0

osayilgan
osayilgan

Reputation: 5893

It's an easy mistake. You are trying to clear a List of Beacons, but not your list, the list instance you receive from the method. Use "this" to access your beacon in your list fragment. and add the beacons you receive from the method. this should fix it.

// this does not work if i call it from the main Activity
public void updateList(List<Beacon> beacons) {
    // Call this to refer your variable in List fragment
    this.beacons.clear();
    this.beacons.addAll(beacons);
    ((MyListAdapter) getListAdapter()).notifyDataSetChanged();
}

Upvotes: 1

Related Questions