woong's

Android viewpager indicator 사용하기 본문

Develop/Android

Android viewpager indicator 사용하기

dlsdnd345 2016. 2. 14. 19:13

Android viewpager indicator 사용하기


안녕하세요. android 개발을 하다보면 viewPager를 많이 사용하게 됩니다.

viewPager 를 사용하게 되면 indicator 도 자연스럽게 자주 사용하게 됩니다.

이번 구글 플레이 스토어 indicator 를 보니 scale Animation 을 통해서

디테일한 indicator 를 사용하고 있습니다.

이런 디테일에서 앱이 이쁘게 나타나고 실력이 차이나 나는것 같습니다.

그래서 scale animation 이 되는 indicator customView 로 만들어서

바로바로 사용할수 있도록 컴포넌트화 시켜서 사용해보려 합니다.


코드는 첨부파일에 첨부 하였습니다.






1. 준비

 - indicator 확인하기 위해서 기본 viewPager 를 구성 했습니다.


2. 사용

 - indicator 핵심 코드만 설명 드리겠습니다.


indicator 를 커스텀 뷰로 만들었습니다.

itemMargin을 통해서 사이 간격을 조절 할수 있고 ,

animDuration 을통해서 원이 작아지고 , 커지는 애니메이션 시간을 조절 할수 있습니다.


createDotPanel 을 호출하면 indicator 가 화면에 나타 납니다.

selectDot 을 호출하면 , 원이 커지면서 선택 이미지로 교체 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
public class CircleAnimIndicator extends LinearLayout{
 
    private Context mContext;
 
    //원 사이의 간격
    private int itemMargin = 10;
 
    //애니메이션 시간
    private int animDuration = 250;
 
    private int mDefaultCircle;
    private int mSelectCircle;
 
    private ImageView[] imageDot;
 
    public void setAnimDuration(int animDuration) {
        this.animDuration = animDuration;
    }
 
    public void setItemMargin(int itemMargin) {
        this.itemMargin = itemMargin;
    }
 
    public CircleAnimIndicator(Context context) {
        super(context);
 
        mContext = context;
    }
 
    public CircleAnimIndicator(Context context, AttributeSet attrs) {
        super(context, attrs);
 
        mContext = context;
    }
 
 
    /**
     * 기본 점 생성
     * @param count 점의 갯수
     * @param defaultCircle 점의 이미지
     */
    public void createDotPanel(int count , int defaultCircle , int selectCircle) {
 
        mDefaultCircle = defaultCircle;
        mSelectCircle = selectCircle;
 
        imageDot = new ImageView[count];
 
        for (int i = 0; i < count; i++) {
 
            imageDot[i] = new ImageView(mContext);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams
                    (LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.topMargin = itemMargin;
            params.bottomMargin = itemMargin;
            params.leftMargin = itemMargin;
            params.rightMargin = itemMargin;
            params.gravity = Gravity.CENTER;
 
            imageDot[i].setLayoutParams(params);
            imageDot[i].setImageResource(defaultCircle);
            imageDot[i].setTag(imageDot[i].getId(), false);
            this.addView(imageDot[i]);
        }
 
 
        //첫인덱스 선택
        selectDot(0);
    }
 
 
    /**
     * 선택된 점 표시
     * @param position
     */
    public void selectDot(int position) {
 
        for (int i = 0; i < imageDot.length; i++) {
            if (i == position) {
                imageDot[i].setImageResource(mSelectCircle);
                selectScaleAnim(imageDot[i],1f,1.5f);
            } else {
 
                if((boolean)imageDot[i].getTag(imageDot[i].getId()) == true){
                    imageDot[i].setImageResource(mDefaultCircle);
                    defaultScaleAnim(imageDot[i], 1.5f, 1f);
                }
            }
        }
    }
 
 
    /**
     * 선택된 점의 애니메이션
     * @param view
     * @param startScale
     * @param endScale
     */
    public void selectScaleAnim(View view, float startScale, float endScale) {
        Animation anim = new ScaleAnimation(
                startScale, endScale,
                startScale, endScale,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setFillAfter(true);
        anim.setDuration(animDuration);
        view.startAnimation(anim);
        view.setTag(view.getId(),true);
    }
 
 
    /**
     * 선택되지 않은 점의 애니메이션
     * @param view
     * @param startScale
     * @param endScale
     */
    public void defaultScaleAnim(View view, float startScale, float endScale) {
        Animation anim = new ScaleAnimation(
                startScale, endScale,
                startScale, endScale,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setFillAfter(true);
        anim.setDuration(animDuration);
        view.startAnimation(anim);
        view.setTag(view.getId(),false);
    }
}
 
 
 
cs



커스텀뷰 사용방법

initIndicator가 핵심 코드입니다.

사이 간격을 조절하고 , 애니메이션 시간을 지정했습니다.

그후에 Indicator를 생성 했습니다.


선택은 ViewPager OnPageChangeListener에서 viewPager가 선택될때

selectDot을 호출해서 애니메이션을 통한 자연스러운 효과를 표현해 보았습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public class MainActivity extends AppCompatActivity {
 
    private ViewPager viewPager;
 
    private List<String> numberList;
 
    private CircleAnimIndicator circleAnimIndicator;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        initLayout();
        init();
    }
 
 
    /**
     * 레이아웃 초기화
     */
    private void initLayout(){
 
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        circleAnimIndicator = (CircleAnimIndicator) findViewById(R.id.circleAnimIndicator);
    }
 
 
    /**
     * 데이터 초기화
     */
    private void init(){
 
        //데이터 초기화
        initData();
        //ViewPager 초기화
        initViewPager();
    }
 
 
    /**
     * 데이터 초기화
     */
    private void initData(){
 
        numberList = new ArrayList<>();
        numberList.add("1");
        numberList.add("2");
        numberList.add("3");
        numberList.add("4");
        numberList.add("5");
 
    }
 
 
    /**
     * ViewPager 초기화
     */
    private void initViewPager(){
 
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getApplicationContext(),numberList);
        viewPager.setAdapter(viewPagerAdapter);
        viewPager.addOnPageChangeListener(mOnPageChangeListener);
 
 
        //Indicator 초기화
        initIndicaotor();
    }
 
 
    /**
     * Indicator 초기화
     */
    private void initIndicaotor(){
 
        //원사이의 간격
        circleAnimIndicator.setItemMargin(15);
        //애니메이션 속도
        circleAnimIndicator.setAnimDuration(300);
        //indecator 생성
        circleAnimIndicator.createDotPanel(numberList.size(), R.drawable.indicator_non , R.drawable.indicator_on);
    }
 
 
    /**
     * ViewPager 전환시 호출되는 메서드
     */
    private ViewPager.OnPageChangeListener mOnPageChangeListener = new ViewPager.OnPageChangeListener() {
 
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
 
        @Override
        public void onPageSelected(int position) {
            circleAnimIndicator.selectDot(position);
        }
 
        @Override
        public void onPageScrollStateChanged(int state) {
        }
    };
 
 
}
 
 
 
cs



xml 코드

커스텀 뷰를 정의하고 위치하고 싶은곳에 위치하면 위 기능들을 통해서 인디케이터가 구성됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000">
 
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
    <com.android.woong.viewpagerindicator.custom.CircleAnimIndicator
        android:id="@+id/circleAnimIndicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp" />
 
 
</RelativeLayout>
 
 
 
cs

Comments