전편에 쓰다가 못 쓴거 마저 쓰기!!

전편 필요한분.
2012/02/08 - [Android Study] - Android List에 index를 표시해보자 3편

protected Locale getLocale() {
    return Locale.getDefault();
}

static final String PHONEBOOK_COLLATOR_NAME = "PHONEBOOK";

private static final class AddressBookIndexQuery {
    public static final String LETTER = "letter";
    public static final String TITLE = "title";
    public static final String COUNT = "count";

    public static final String[] COLUMNS = new String[] {
            LETTER, TITLE, COUNT
    };

    public static final int COLUMN_LETTER = 0;
    public static final int COLUMN_TITLE = 1;
    public static final int COLUMN_COUNT = 2;

    public static final String ORDER_BY = LETTER + " COLLATE " +           
                                                         PHONEBOOK_COLLATOR_NAME;
}


남은 부분은 이게 단데... 

솔직히 여기서부터는 설명할 방법이... 찾기도 귀찮고...
게다가 구글에서 개발 해놓은 거라... 겐히 저작권 문제에 휘말리지 않을까? 싶기도하고...

여튼 Provider에서 처리해야 할 내용은 이게 다임...으힛...
담에는 이걸 Adapter 에서 사용 하는 꼴? 을 보여주겠음 움케케 (to be continue after 1 year



전편에 이어서 이제부턴 code 부연 설명 및 추가 code !!

전편 못 본분 여기!!
2012/02/08 - [Android Study] - Android List에 index를 표시해보자 2편



private Cursor bundleLetterCountExtras(Cursor cursor, final SQLiteDatabase db,
        SQLiteQueryBuilder qb, String selection, String[] selectionArgs, String sortOrder) {
    String sortKey;
    String sortOrderSuffix = "";

    // Sortkey 설정 부분 - 전낸 중요함 왜 냐면 index 뽑을 때 소트키로 뽑음 그러므로 NULL 안댐
    if (sortOrder != null) {
        int spaceIndex = sortOrder.indexOf(' ');
        if (spaceIndex != -1) {
            sortKey = sortOrder.substring(0, spaceIndex);
            sortOrderSuffix = sortOrder.substring(spaceIndex);
        } else {
            sortKey = sortOrder;
        }
    }

    // 실제 sortkey로 사용 될 부분 위에서 지정한 sortkey가 null 이면 안되는 이유가 여기임!!    
    String subSortKey = "SUBSTR(" + sortKey + ",1,1)";

    // 국가 세팅 얻어오기 (국가별로 sort 내용이 다르니까!!)
    String locale = getLocale().toString();

    // Projection list 만들기 (이거 좀 신기함, 내가 Android SQL은 안까봐서 모르겠는데...
    // 일케도 돌아가나 봄. (아니면 특별히 만든 내용일 확률이 99.9%이긴 한데...)
    HashMap projectionMap = new HashMap();

    // 빨간색 글귀 변경되면 안됨. SQL에서 따로 만들어 놓은 거라서 변경되면 안됨.
    // 변경되면 뭐랄까? 인식을 못 한다고나 할까? Error 날꺼임.. 
    // 추가로 google애들이 적어 놓은 주석을 알려주자면
    
    /**
     * Use the GET_PHONEBOOK_INDEX function, which is an android extension for SQLite3,
     * to map the first letter of the sort key to a character that is traditionally
     * used in phonebooks to represent that letter.  For example, in Korean it will
     * be the first consonant in the letter; for Japanese it will be Hiragana rather
     * than Katakana.
     */
    
     projectionMap.put(AddressBookIndexQuery.LETTER,
             subSortKey + " AS " + AddressBookIndexQuery.LETTER);
 
     projectionMap.put(AddressBookIndexQuery.TITLE,
            "GET_PHONEBOOK_INDEX(" + subSortKey + ",'" + locale + "')"
                    + " AS " + AddressBookIndexQuery.TITLE);

      projectionMap.put(AddressBookIndexQuery.COUNT,
            "COUNT(" + sortKey + ") AS " + AddressBookIndexQuery.COUNT);
 
     // Projection setting 해주기
      qb.setProjectionMap(projectionMap);

     // Query 돌리기!!
      Cursor indexCursor = qb.query(db, null, selection, selectionArgs,
            AddressBookIndexQuery.ORDER_BY, null /* having */,
            AddressBookIndexQuery.ORDER_BY + sortOrderSuffix);

      try {
          int groupCount = indexCursor.getCount();
          String titles[] = new String[groupCount];
          int counts[] = new int[groupCount];
          int indexCount = 0;
          String currentTitle = null;

          int count = 0;

         // 중복된 내용들은 정리하고 배열에 정리해 넣기
           for (int i = 0; i < groupCount; i++) {
              indexCursor.moveToNext();
              int latter = indexCursor.getInt(AddressBookIndexQuery.COLUMN_LETTER);
              String title = indexCursor.getString(AddressBookIndexQuery.COLUMN_TITLE);

              count = latter;
              if (indexCount == 0 || !TextUtils.equals(title, currentTitle)) {
               // titles 이게 index 글자들 배열
                  titles[indexCount] = currentTitle = title;
               // index의 position 배열 (2편에서 query 문에 의해 나온
               // bundleLetterCountExtras 여기 들어 오기전 cursor에서 position)
                  counts[indexCount] = count;
                  indexCount++;
              } else {
                counts[indexCount - 1] += count;
            }
        }

       // 배열 크기 조정
        if (indexCount < groupCount) {
            String[] newTitles = new String[indexCount];
            System.arraycopy(titles, 0, newTitles, 0, indexCount);
            titles = newTitles;

            int[] newCounts = new int[indexCount];
            System.arraycopy(counts, 0, newCounts, 0, indexCount);
            counts = newCounts;
        }

       // Bundle 형태로 담아서 cursor에 몰래 꼽아둠 ㅋㅋ
        final Bundle bundle = new Bundle();
       // 빨간색 부분은 Bundle 에서 Extra key 값임 알아서 처리 하셈
        bundle.putStringArray("님덜 맘대로", titles);
        bundle.putIntArray("님덜 맘대로", counts);
        return new CursorWrapper(cursor) {

            @Override
            public Bundle getExtras() {
                return bundle;
            }
        };
    } finally {
        indexCursor.close();
    }
}
으하하하 너무 길어서 담편에 부족한 code 추가 해야겠네...?
데헷~ 너무 좋다.
 


 
저번 글에 뻘짓만 하고 code 안알려줘서 빡친 분들 더러 더러 있을 꺼 같아서
인좌부터 code로 까 놓고 직접 설명 해줄께요.

(님들아 돌 내려놔여...)

기본 가정으로 ListView, Adapter, Provider 구성은 할 줄 안다고 가정 하고 시작 합니다.

기본 코드 출처는 ContactsProvider에 있었음.
(다년 간? 다뤄본 경험에 비추어 가장 좋은 방법? 이라고 판단됨 - 지극히 주관적 ㅋㅋ)

우선 Provider 에서 query 부분을 수정 해야함.
대부분 보통 상태라면 cursor를 return 해야 되기 땜시롱.
 

 case DATA :
 Cursor cursor = database.query(테이블명, 프로젝션, 조건문, 조건문인자, 그룹바이, 해빙, 소트)
 break;
 

요딴식으로 되어 있을 꺼임. 이걸 수정을 가해서 index를 같이 전달 해주도록 고칠 예정임


case DATA :
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
Cursor cursor = database.query(테이블명, 프로젝션, 조건문, 조건문인자, 그룹바이, 해빙, 소트)
qb.setTables(테이블명);
// 요고는 안써도 되는듯 
// qb.setStrictProjectionMap(true);
cursor = bundleLetterCountExtras(cursor,  database, qb, selection, selectionArgs, sortOrder);

일케 고치고 나면.

bundleLetterCountExtras(cursor,  database, qb, selection, selectionArgs, sortOrder);

이 함수 부분이 매우 궁금 할 꺼임? 글치 않음 님덜?



private Cursor bundleLetterCountExtras(Cursor cursor, final SQLiteDatabase db,
        SQLiteQueryBuilder qb, String selection, String[] selectionArgs, String sortOrder) {
    String sortKey;
    String sortOrderSuffix = "";
    if (sortOrder != null) {
        int spaceIndex = sortOrder.indexOf(' ');
        if (spaceIndex != -1) {
            sortKey = sortOrder.substring(0, spaceIndex);
            sortOrderSuffix = sortOrder.substring(spaceIndex);
        } else {
            sortKey = sortOrder;
        }
    }
    
    String subSortKey = "SUBSTR(" + sortKey + ",1,1)";

    String locale = getLocale().toString();
    HashMap projectionMap = new HashMap();
    projectionMap.put(AddressBookIndexQuery.LETTER,
            subSortKey + " AS " + AddressBookIndexQuery.LETTER);

    projectionMap.put(AddressBookIndexQuery.TITLE,
            "GET_PHONEBOOK_INDEX(" + subSortKey + ",'" + locale + "')"
                    + " AS " + AddressBookIndexQuery.TITLE);

    projectionMap.put(AddressBookIndexQuery.COUNT,
            "COUNT(" + sortKey + ") AS " + AddressBookIndexQuery.COUNT);

    qb.setProjectionMap(projectionMap);

    Cursor indexCursor = qb.query(db, null, selection, selectionArgs,
            AddressBookIndexQuery.ORDER_BY, null /* having */,
            AddressBookIndexQuery.ORDER_BY + sortOrderSuffix);

    try {
        int groupCount = indexCursor.getCount();
        String titles[] = new String[groupCount];
        int counts[] = new int[groupCount];
        int indexCount = 0;
        String currentTitle = null;

        int count = 0;

        for (int i = 0; i < groupCount; i++) {
            indexCursor.moveToNext();
            int latter = indexCursor.getInt(AddressBookIndexQuery.COLUMN_LETTER);
            String title = indexCursor.getString(AddressBookIndexQuery.COLUMN_TITLE);

            count = latter;
            if (indexCount == 0 || !TextUtils.equals(title, currentTitle)) {
                titles[indexCount] = currentTitle = title;
                counts[indexCount] = count;
                indexCount++;
            } else {
                counts[indexCount - 1] += count;
            }
        }

        if (indexCount < groupCount) {
            String[] newTitles = new String[indexCount];
            System.arraycopy(titles, 0, newTitles, 0, indexCount);
            titles = newTitles;

            int[] newCounts = new int[indexCount];
            System.arraycopy(counts, 0, newCounts, 0, indexCount);
            counts = newCounts;
        }

        final Bundle bundle = new Bundle();
        bundle.putStringArray("님덜 맘대로", titles);
        bundle.putIntArray("님덜 맘대로", counts);
        return new CursorWrapper(cursor) {

            @Override
            public Bundle getExtras() {
                return bundle;
            }
        };
    } finally {
        indexCursor.close();
    }
 }
뭔가 내가 쓰긴 했지만 전낸 머리 아픔... 주석도 없고...
글구 몇가지 또 빼먹은 것도 있고 움케케케... 하지만 나머지 설명은 3탄에 할 계획이란거!!
난 이걸로 12편까지 만들고 싶...  (응? 거기 퍼갈땐 댓글!!)




아이폰을 사용 하다 보면 어떤 어플에서는 list에 index를 표시 해주는 것을 볼 수 있다.
그럼 안드로이드에는 list에 index를 표기 하는 법이 없을까?(쓸대없는 호기심 발동 ㅋㅋ)


근데 그냥 안된다. 망할 Android... OTL


I : "Hey android, do you have this component?"


 


A : "Sure. yes i do."

위 영어 표기가 정상인지는 몰겠지만.. 무튼 나도 저거 해보고 싶었다.
그래서 여기저기 뒤져봤다.
뒤져보니 여간 깐깐한게 아니다.
그래서 감히 말하건데... Listview, Adapter, Provider 모르는 사람은 그냥 포기해라.
(다른 방법도 있지만 그건 안알려 줄테다. ^^)

글구 퍼가는거 좋은데 출처 분명히 해줬으면 함. (퍼가긴 할껀지 몰겠네.)

'Android' 카테고리의 다른 글

Android List에 index를 표시해보자 3편  (0) 2012.02.08
Android List에 index를 표시해보자 2편  (0) 2012.02.08
Android base component - ListView  (0) 2011.10.20
Android - Activity  (0) 2011.10.02
Android 시작  (0) 2011.09.20


(구글링 하다가 퍼온 사진임 저작권 문제가 생기면 내리겠음)

지금에 와서야 Android를 이야기 시작 한다는게 많이 늦었다는 생각이 든다.
나는 코딩을 엄청 잘하는 개발자도 아니고, 내 전공이 컴공은 더욱더 아니다. 그래서 하는 말인데...
코드를 좀 쉽게 이야기를 해보고 싶었다는... 비록 말로 끝날지 모르겠지만

비록 Google 에서 Motorola를 인수하면서 좀 많이 걱정 되는 것도 사실이긴 한데 뭐 배워둬서 나쁠껀
없다고 생각이 듬.

각종 블로그나 인터넷 정보에 따르면 Android에 관한 자료들이 무진장? 있을 수도 있고 없을 수도 있고.
무튼 처음 환경 setting 이라던지 기타 내용들은 이미 자세히 나와 있으니까... 여러곳에서 구하시고

기본 준비 내용은 Eclipse, SDK, JDK, 환경변수, Hello Android 정도?

+ Recent posts