Fast scroll thumb disappears while scrolling AlphabetIndexer
Asked Answered
D

4

31

I have a ListView with fastScrollAlwaysVisible and fastScrollEnabled both set to true. After implementing SectionIndexer to my Adapter and an AlphabetIndexer, my fast scroll thumb will disappear while I scroll, then reappear once I reach the top or bottom of the list. I'm pretty clueless about why this happens. I haven't experienced it before.

Everything below works as far as AlphabetIndexer is concerned. My question is why does my fast scroll thumb disappear while I scroll and how can I stop it from disappearing?

Whether or not the fast scroll is always visible doesn't matter. Whenever the fast scroll is visible, the fast scroll thumb is not there, it's simply gone and that's my problem. Also, when I remove the AlphabetIndexer the fast scroll thumb works like I intend for it to. Everything works successfully in an Activity, but when I load my ListView in a Fragment things end up like I explain.

This is my Adapter for my ListView:

private class AlbumsAdapter extends SimpleCursorAdapter implements
        SectionIndexer {

private AlphabetIndexer mIndexer;

// I have to override this because I'm using a `LoaderManager`
@Override
    public Cursor swapCursor(Cursor cursor) {

        if (cursor != null) {
            mIndexer = new MusicAlphabetIndexer(cursor, mAlbumIdx,
                    getResources().getString(R.string.fast_scroll_alphabet));
        }
        return super.swapCursor(cursor);
    }

    @Override
    public Object[] getSections() {
        return mIndexer.getSections();
    }

    @Override
    public int getPositionForSection(int section) {
        return mIndexer.getPositionForSection(section);
    }

    @Override
    public int getSectionForPosition(int position) {
        return 0;
    }
}

MusicAlphabetIndexer helps sort through music correctly:

class MusicAlphabetIndexer extends AlphabetIndexer {

public MusicAlphabetIndexer(Cursor cursor, int sortedColumnIndex,
        CharSequence alphabet) {
    super(cursor, sortedColumnIndex, alphabet);
}

@Override
protected int compare(String word, String letter) {
    String wordKey = MediaStore.Audio.keyFor(word);
    String letterKey = MediaStore.Audio.keyFor(letter);
    if (wordKey.startsWith(letter)) {
        return 0;
    } else {
        return wordKey.compareTo(letterKey);
    }
  }
}
Dalessandro answered 20/3, 2012 at 2:56 Comment(3)
I am doing something similiar HERE #10224733Mask
I took at your post and didn't see anything wrong. My SectionIndexer works and doesn't show as you scroll and it seems you're having the opposite problem, weird. I'm starting to think Fragments are the culprit, but I'm unsure how right now. I think they are because my SectionIndexer works in a ListActivity.Dalessandro
I'll try to see if I can recreate your issues.Lowrance
D
7

I had similar issue with fast scroller's thumb icon. I was investigating Android source code and found a commit which introduced this problem and other (ArrayIndexOutOfBoundsException). I built even Android system without this commit and it worked then.

I submitted the issue in June: https://code.google.com/p/android/issues/detail?id=33293
When I'm reading it know I see I could describe the issue better :)

This is the commit which is making problems: https://github.com/android/platform_frameworks_base/commit/32c3a6929af9d63de3bf45a61be6e1a4bde136d3

Unfortunately I haven't found any solution, except revert the commit, and I left it.
I hope someone will find how to fix it.

Deannedeans answered 20/11, 2012 at 10:8 Comment(1)
Yeah, I suspected that it was a framework bug. I've also seen other apps in the Play Store experience the same thing. I"m glad you posted this.Dalessandro
F
2

Do you have both fastScrollEnabled and fastScrollAlwaysVisible set to true? There is no fastScrollAlwaysEnabled attribute of a ListView, so I'm thinking maybe you just have fastScrollEnabled set to true but fastScrollAlwaysVisible is set to its default value, which is false.

Frequent answered 24/3, 2012 at 12:53 Comment(1)
Oh, wow. That's actually a typo. I did mean fastScrollAlwaysVisible. I also have fastScrollEnabled set to true. I actually updated my OP a little more. Thanks for commenting, I never would have noticed I made a typo.Dalessandro
L
0

You can check this code:

int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion <= android.os.Build.VERSION_CODES.FROYO){
    // Do something for froyo and above versions
    list.setFastScrollEnabled(true);


} else if(currentapiVersion > android.os.Build.VERSION_CODES.HONEYCOMB){
    // do something for phones running an SDK before froyo
    list.setFastScrollEnabled(true);
    list.setFastScrollAlwaysVisible(true);
}
Liber answered 4/5, 2016 at 17:14 Comment(2)
Wow, that code gets around! Suggest you provide attribution for code you've found. (The basic structure is from docs, right?)Distressed
setFastScrollAlwaysVisible -> Set whether or not the fast scroller should always be shown in place of the standard scroll bars.Liber
N
-2

Activity

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.AlphabetIndexer;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.SimpleCursorAdapter;

public class TestAct extends Activity {
    /** Called when the activity is first created. */
    ListView test_listView;
    Cursor myCursor;
    String[] proj;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_app_test);

        TestDummyData cTestDummyData = new TestDummyData(
                getApplicationContext());
        cTestDummyData.open();
        cTestDummyData.insertRandomNames();
        myCursor = cTestDummyData.fetchAllData();

        test_listView = (ListView) findViewById(R.id.pager_list_test);
        test_listView.setFastScrollEnabled(true);

        test_listView.setAdapter(

        new MyCursorAdapter(getApplicationContext(),
                android.R.layout.simple_list_item_1, myCursor,
                new String[] { TestDummyData.KEY_NAME },// names
                new int[] { android.R.id.text1 })

        );

        cTestDummyData.close();

    }

    class MyCursorAdapter extends SimpleCursorAdapter implements SectionIndexer {

        AlphabetIndexer alphaIndexer;

        // HashMap<String, Integer> alphaIndexer;
        // String[] sections;
        public MyCursorAdapter(Context context, int layout, Cursor c,
                String[] from, int[] to) {
            super(context, layout, c, from, to);

            alphaIndexer = new AlphabetIndexer(c,
                    myCursor.getColumnIndex(TestDummyData.KEY_NAME),
                    " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            // ======optional way to get alphaindexer from data
            // alphaIndexer = new HashMap<String, Integer>();
            // int size = items.size();
            //
            // for (int x = 0; x < size; x++) {
            // String s = items.get(x);
            //
            // String ch = s.substring(0, 1);
            //
            // ch = ch.toUpperCase();
            //
            // alphaIndexer.put(ch, x);
            // }
            //
            // Set<String> sectionLetters = alphaIndexer.keySet();
            //
            // ArrayList<String> sectionList = new ArrayList<String>(
            // sectionLetters);
            //
            // Collections.sort(sectionList);
            //
            // sections = new String[sectionList.size()];
            //
            // sectionList.toArray(sections);

        }

        @Override
        public int getPositionForSection(int section) {
            // TODO Auto-generated method stub
            return alphaIndexer.getPositionForSection(section);
        }

        @Override
        public int getSectionForPosition(int position) {
            // TODO Auto-generated method stub
            return alphaIndexer.getSectionForPosition(position);
        }

        @Override
        public Object[] getSections() {
            // TODO Auto-generated method stub
            return alphaIndexer.getSections();
        }

    }

}

Class To use Dummy Data For listing

import java.util.Random;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class TestDummyData {

    static final String KEY_ID = "_id";
    static final String KEY_NAME = "name";

    private static final String DB_NAME = "tutorial";
    private static final String TABLE_NAME = "names";
    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_CREATE = "create table " + TABLE_NAME
            + " (" + KEY_ID + " integer primary key autoincrement, " + KEY_NAME
            + " varchar not null);";

    private Context context;
    private DatabaseHelper dbHelper;
    private SQLiteDatabase db;

    public TestDummyData(Context context) {
        this.context = context;
        this.dbHelper = new DatabaseHelper(this.context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.v("DBUTIL", "Upgrading database from version " + oldVersion
                    + " to " + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }

    public void open() {
        db = dbHelper.getWritableDatabase();
    }

    public void close() {
        dbHelper.close();
    }

    public void insertRandomNames() {
        db.execSQL("DELETE FROM " + TABLE_NAME);
        String s = "ANDROIDDEVELOPER";
        Random r = new Random();

        ContentValues values = new ContentValues();
        for (int i = 0; i < 200; i++) {
            values.clear();
            values.put(KEY_NAME, s.substring(r.nextInt(s.length())));
            db.insert(TABLE_NAME, null, values);
        }
    }

    public Cursor fetchAllData() {
        return db.rawQuery("SELECT * FROM " + TABLE_NAME + " ORDER BY "
                + KEY_NAME + " ASC", null);
    }

}

the above class is dummy data clss for common task... list_app_test.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<ListView 
android:id="@+id/pager_list_test" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content">
</ListView>

</LinearLayout>

you have just give test_listView.setFastScrollEnabled(true); gvn ans whter i cn understand from ur quest.

Notify answered 18/4, 2012 at 7:9 Comment(2)
This isn't helpful. I know how to implement a SectionIndexer. What I don't know is why the fast scroll thumb disappears while I scroll.Dalessandro
This is possibly the least useful answer I've ever come across.Carnahan

© 2022 - 2024 — McMap. All rights reserved.