안드로이드 PullToRefresh 오픈소스 2가지의 구현방식



안드로이드의 새로고침 View중 가장 흔하게 쓰이는 것은 Chris Banes가 오픈소스로 공개한 PullToRefresh이다. 현재 지원이중단된 Android-PullToRefresh와 새롭게 만든 ActionBar-PullToRefresh 2가지의 종류로 구분된다.



Android-PullToRefresh의 구현 방식

ListView에 Layout을 한번더 감싸서 터치이벤트에 대한 처리를 통해 새로고침 콜백을 처리 하는 방식으로 각각의 스크롤되는 View에 대해 새로고침 View를 구현했다.

 


ActionBar-PullToRefresh의 구현방식

Layout의 터치이벤트에 대한 새로고침 상태를 콜백(delegate) 해주는 방식이다. PullToRefreshLayout을 통해 내부에 스크롤되는 뷰가 있다면 새로고침에 대한 콜백을 제공해주어 개발자는 다양한 형태 새로고침 상태에 대한 View를 만들 수 있다.

 

<uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ptr_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <GridView
        android:id="@+id/ptr_gridview"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:numColumns="auto_fit"
        android:verticalSpacing="1dp"
        android:horizontalSpacing="1dp"
        android:columnWidth="100dp"
        android:stretchMode="columnWidth"
        android:gravity="fill" />


</uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout>

 

Android-PullToRefresh에서 ActionBar-PullToRefresh의 코드가 상당량 줄었으며, 스크롤되는 뷰와 의존적이지 않기 때문에 확장성이 높다. 예전에 ListView를 커스텀 하는 경우 PullToRefresh코드를 일부 수정해야 했었는데, 현재 버전에서는 그럴일이 전혀 없어졌다.

 

레이아웃 내부의 스크롤되는 View를 찾아서 HeaderTransformer를 통해 새로고침에 대한 상태를 콜백 해준다. 새로고침 중, 시작, 보이기, 숨기기등에 대한 상태를 알려주며 여기에 맞게 개발자는 View상태를 구현하면 된다.

 

 

 




오픈소스 라이브러리의 양면성

요즘 안드로이드 뷰 관련 오픈소스들이 다양하게 많아 졌다. 그 중 Android-PullToRefresh가 가장 흔히 사용되는 뷰중 하나일것이다. 오픈소스를 사용하는 목적을 생각해보면 서비스의 해당기능을 쉽게 쓸수 있다는 것과 어느정도 검증이 끝나서 약간의 안정성이 있다. 하지만 여기에 함정이 있다. 오픈소스는 완벽한 안정성을 제공하지 않고, 점점 안정화되고 있는 과정이며, 내부에 어떤일들을 하고 있는지 인지 하고 있지 못한 상태에서 사용하다가 문제가 생길경우 문제를 찾기가 대단히 어려울 가능성이 있다. 즉, 사용하기 편하고 안정성이 있다고 해도 그만큼 양면성의 문제점이 있다. 

얼마전 Android-PullToRefresh 뷰를 사용하다가 문제점을 발견했다. Android-PullToRefresh로 리스트뷰 새로고침 기능을 만드는데, 사용자가 직접 행위 하지 않고 코드를 통해 Refresh View를 보여주게 하는 setRefreashing() 메소드를 제공하고 있다. 

일반적 구조는 사용자가 직접 뷰를 내려 Refreash하거나 setRefreashing() 메소드를 호출하게 되면 onRefreash() Listener가 호출되게 되며 여기서 데이터를 새로 불러오는 작업후 onRefreashComplet() 메소드 호출을 통해 새로고침 View를 Hide할 수 있다. 

내부 구조를 보면 ListView의 adapter의 상태에 따라 onRefreash() Listener의 호출을 체크 하는 부분이 있다. 이 부분을 보면 adapter가 null이거나 empty일 결우 return하게 된다. 즉, onRefreash() Listener가 호출 되지 않는다는 것이다. 

PullToRefreshListView.java 

@Override
protected void onRefreshing(final boolean doScroll) {
    /**
     * If we're not showing the Refreshing view, or the list is empty, the
     * the header/footer views won't show so we use the normal method.
     */
    ListAdapter adapter = mRefreshableView.getAdapter();
    if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
        super.onRefreshing(doScroll);
        return;
    }

    super.onRefreshing(false);

       //....이하 생략
}

즉, setRefreashing()하기전 ListView의 adapter의 데이터는 있어야 onRefreash() Listener가 호출 된다. adapter에 데이터가 없다면 onRefreash() Listener가 호출 되지 않아 문제가 생긴다. 예를 들어 Activity onCreate에서 데이터를 네크워크를 통해가져 올때 Refreashing 중으로 View를 보이게 하고 싶을때 문제가 발생 된다. 데이터를 불러오기 전(adapter가 비어있는 상황)에 setRefreashing()를 호출 할 것이기 때문이다. 

Android-PullToRefresh Sample에도 이런 설명은 없다. Sample을 보면 항상 adapter에 dummy데이터를 넣고 시작 하기 때문이 이런 문제점을 발견하기 힘들다. 그렇다면 오픈소스를 사용할때 이런 문제점을 발견 할 수 없을까? 

오픈소스를 Copy&Paste로 눈에 보이는 결과물에 대해서 유혹당하지 말자. 

Sample코드로 테스트해보되 내부 Library를 하나씩 따라가보면서 구조를 분석 하자. 

시간이 된다면 직접 오픈소스를 개발해보는 경험을 해보자.

오슨소스는 완벽한 라이브러리가 아닌 만들어가는 과정이기에 언제 어떤 문제가 발생 될지 모른다. Copy&Paste에만 급급 한다면 언젠가는 편했던 시간들에 대한 보상을 해야 하는 날이 올 것이다. 이 글을 보는 모든 개발자들도 이런 오픈소스의 양면성에 대해 주의했으면 좋겠다. 

Android View 관련된 오픈소스 정리

Android View와 관련된 오픈소스들이 많이 공개 되고 있다. 그래서 많이 쓰이고 유용한 오픈소스를 정리 해보았다.  아직 국내에서는 오픈소스가 인색한지 모두 외국에서 만든것들이다. 나도 View관련 오픈소스를 하나준비 하겠다고 준비중인데.. 준비중이기만 하다.

 

참고로, 잘 알려지고 검증된 오픈소스라도 코드를 하나하나씩 보고 어떻게 구현되어 있는지 꼭 살펴보고 썼으면 좋겠다. 그리고 이제 개발을 시작한지 얼마 안된 분들이라면 이런 오픈소스를 사용함으로 자기 실력을 죽일 수도 있으니 한번씩 구현해보는 것도 좋을듯 하다.

 

그리고 국내 개발 커뮤니티에 보면 자기가 개발할 것에 대해 오픈소스를 찾음으로써 개발해서 삽질 하기전에 찾아서 다행이다라는 글들을 보면 씁쓸하다. 오픈소스는 좋은점도 있지만 그에 반하는 양면성을 가지고 있다는 것에 조심했으면 좋겠다.

 

 

아무튼 아래것들은 이미 유명하고 잘만들어진 오픈소스들이다.

 

 

 

 

1. ActionbarSherlock

허니컴부터 적용된 액션바를 이전버전에도 사용할 수 있게 해준다.

 

http://www.actionbarsherlock.com/
https://github.com/JakeWharton/ActionBarSherlock

 

ActionBarSherlock is an standalone library designed to facilitate the use of the action bar design pattern across all versions of Android through a single API.

The library will automatically use the native ActionBar implementation on Android 4.0 or later. For previous versions which do not include ActionBar, a custom action bar implementation based on the sources of Ice Cream Sandwich will automatically be wrapped around the layout. This allows you to easily develop an application with an action bar for every version of Android from 2.x and up.

 

 

 

2. Android-PullToRefresh

ListView, ScrollView, Viewpager, WebView 등 새로고침 기능의 View를 만들어 준다.

 

https://github.com/chrisbanes/Android-PullToRefresh

 

This project aims to provide a reusable Pull to Refresh widget for Android. It was originally based on Johan Nilsson’s library (mainly for graphics, strings and animations), but these have been replaced since.

 

 

 

 

3. StickyListHeaders

ListView의 Section Header 정보를 넣을 수 있다.

 

https://github.com/emilsjolander/StickyListHeaders

 

StickyListHeaders is an Android library that makes it easy to integrate section headers in your ListView. These section headers stick to the top like in the new People app of Android 4.0 Ice Cream Sandwich. This behavior is also found in lists with sections on iOS devices. This library can also be used for without the sticky functionality if you just want section headers.

StickyListHeaders actively supports android versions 2.3 (gingerbread) and above That said, it should be compatible with much older versions of android as well but these are not actively tested.

Here is a short gif showing the functionality you get with this library:

 

 

4. MenuDrawer
좌측 또는 우측의 슬라이드 메뉴를 구성 할 수 있다.

https://github.com/SimonVT/android-menudrawer

 

A slide-out menu implementation, which allows users to navigate between views in your app. Most commonly the menu is revealed by either dragging the edge of the screen, or clicking the ‘up’ button in the action bar.

 

 

5. SlidingMenu
MenuDrawer와 같다.

 

https://github.com/jfeinstein10/SlidingMenu

SlidingMenu is an Open Source Android library that allows developers to easily create applications with sliding menus like those made popular in the Google+, YouTube, and Facebook apps. Feel free to use it all you want in your Android apps provided that you cite this project and include the license in your app.]

 

 

6. FadingActionBar

리스트뷰 스크롤시 헤더 컨텐츠에 따라 액션바의 알파값이 변한다. 구글 음악플레이어의 아티스트정보 페이지

 

https://github.com/ManuelPeinado/FadingActionBar

 

FadingActionBar is a library which implements the cool fading action bar effect that can be seen in the new Play Music app.

 

7. DragSortListView

리스트 소팅

 

https://github.com/bauerca/drag-sort-listview

 

DragSortListView (DSLV) is an extension of the Android ListView that enables drag-and-drop reordering of list items.

 

 

8. IndexableListView

리스트뷰의 알파벳 인덱스 기능

 

https://github.com/woozzu/IndexableListView

 

 

9. ListViewAnimations

ListView 스크롤시 애니메이션(구글 플러스)

 

https://github.com/nhaarman/ListViewAnimations

 

ListViewAnimations is an Open Source Android library that allows developers to easily create ListViews with animations. Feel free to use it all you want in your Android apps provided that you cite this project and include the license in your app.

 

 

10. ViewPagerIndicator

ViewPager 인디케이터

 

https://github.com/JakeWharton/Android-ViewPagerIndicator

 

Android-ViewPagerIndicator is presented as an Android library project. A standalone JAR is not possible due to the theming capabilities offered by the indicator widgets.

 

11. PagerSlidingTabStrip

ViewPager 인디케이터

 

https://github.com/astuetz/PagerSlidingTabStrip

 

Interactive paging indicator widget, compatible with the ViewPager from the Android Support Library.

 

 

12. JazzyViewPager

ViewPager 스크롤시 애니메이션

 

https://github.com/jfeinstein10/JazzyViewPager

 

An easy to use ViewPager that adds an awesome set of custom swiping animations. Just change your ViewPagers to JazzyViewPagers and you’re good to go!

 

 

14. ViewPager3D

ViewPager 스크롤시 3D 효과

 

https://github.com/inovex/ViewPager3D

 

 

15. DirectionalViewPager

ViewPager 좌우, 아래위 스크롤

 

https://github.com/JakeWharton/Android-DirectionalViewPager

 

Implementation of the compatibility library ViewPager class that supports paging both vertically and horizontally as well as changing between the two at runtime.

 

 

 

16. VerticalSeekBarAndroid
수직 SeekBar

 

https://github.com/AndroSelva/Vertical-SeekBar-Android

 

This project is all about Customizing the normal SeekBar to Vertical Seekbar.

 

 

17. HoloCircleSeekBar
원형으로 생긴 SeekBar

 

https://github.com/JesusM/HoloCircleSeekBar

 

A Circle SeekBar inspired by Android Holo ColorPicker designed by Marie Schweiz and developed by Lars Werkman.

 

 

18. MultiChoiceAdapter
ListView, GridView에서 다중선택을 쉽게 할 수 있도록 도와준다.

 

https://github.com/ManuelPeinado/MultiChoiceAdapter

 

MultiChoiceAdapter is an implementation of ListAdapter which adds support for modal multiple choice selection as in the native Gmail app.

 

 

19. TwoWayGridView
GridView를 가로, 세로방향으로 스크롤 되도록 한다.

 

https://github.com/jess-anders/two-way-gridview

 

An Android GridView that can be configured to scroll horizontally or vertically.

 

 

20. ScrollBarPanel
스크롤바 옆에 View를 생성(Path 2.0에서 볼 수 있는 기능)

 

https://github.com/rno/Android-ScrollBarPanel

 

Android-ScrollBarPanel allows to attach a View to a scroll indicator like it’s done in Path 2.0.