4

I'm trying to do something similar to iOS editable UITableView on my App Preferences. Basically it's a list where users can add items, remove them or reorder them. I'm sure this is a common issue but I haven't found any examples on how to do it.

Right now I'm trying to do it by nesting two PreferenceScreens and moving items between them:

enter image description here

I store the items on two different arrays (the "added" items and the "not added" items) and build both screens dynamically with addPreference() however I'm not sure if it's a good idea and neither how to let users remove and reorder items.

How can this be done?

Community
  • 1
  • 1
lisovaccaro
  • 27,544
  • 92
  • 235
  • 388

3 Answers3

1

As I'm not able to find a way to reorder a PreferenceScreen, there goes another approach. You might define an Activity, for instance, and define inside two ListViews. The idea is to play with the visibility property on both of them, so at each time you would set as visible one of them and gone the other one, or gone both of them if you need to do something like your first screenshot.

You'd need to extend an ArrayAdapter for each of them (or have just one ArrayAdapter and use it for both ListViews, changing the layout or the initial dataset, or both). As far as the layout goes, you might simply define a custom layout with a LinearLayout and inside it an ImageView and a TextView to achieve the layout effect shown in your screenshots, something like that:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#000000"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/layoutImage"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:layout_weight="2" 
        android:background="@drawable/..."/>

    <TextView
        android:id="@+id/layoutText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="8"
        android:layout_gravity="left"
        android:numLines="1"
        android:textSize="18sp" />
</LinearLayout>

Once defined, the second parameter of your custom ArrayAdapter is the layout, so you just pass it the R.id.your_new_layout reference and the rows will be created with it.

For the deletion of items, it's easy to achieve since you may simply define an onClickListener() inside your custom adapter's getView() method and remove that item from the data set (which you would keep track inside your ArrayAdapter). ListView has the notifyDataSetChanged() method that will automatically remove the item from your list, you might even add an animation to make it visually more attractive.

The reorder option seems to be the most laborious in this case. ListView by default will render the rows in its "own order", which means that basically you'll see it unsorted. This can be avoided calling the .sort() method over your ArrayAdapter, but you don't want this either because you want to allow your users to reorder the list their way, so I have just 2 ideas that come to my mind (none of them tested):

  • Try to achieve this using onDragEvent. According to this, you might be able to process dragging of a row of your ListView to process some events. This way you can probably see where the user drops the item and reorder the List in your Adapter to stay that way.

  • External libraries. There seems to be some external libraries that already implement this, for example, you might want to see this, this and this.

The main benefit of this approach is that you can have the two data set within the same Activity, where you'll have both adapters reachable and you can easily play around to move data from one instance to another, calling setVisibility() with View.VISIBLE or View.GONE on the ListView that you need, so it makes the flow easier.

Community
  • 1
  • 1
nKn
  • 13,452
  • 9
  • 38
  • 58
0

There is no straightforward way of doing this.
But this implementation should be what you need, with a bit of tweaking.
Download the source code from here.

bosnjak
  • 7,628
  • 2
  • 17
  • 44
0

I would suggest using a DragSortListView, just like the one you can find in Google Play Music.

This implementation is particularly good, both easy to integrate and extremely performant. It should suit your needs for the reordering / deleting part.

Sebastiano
  • 11,909
  • 6
  • 44
  • 77