티스토리 뷰

반응형

앱에서 가장 많이 볼 수 있는 기능을 살펴보면 "좌우 스와이프" 기능을 쉽게 찾을 수 있는데요. 
Android의 스와이프 기능은 다양한 구현 방법이 존재하는데 대표적으로 ViewPager 일 것입니다.

이번 포스트에서 공유 드릴 내용은 ViewPager을 이용한 "Carousel View Pager" 입니다. 

          

위에 사진을 보면 현재 보여지는 화면과 좌우에 이전과 다음에 보여질 화면이 미리 보여집니다.

물론 이동도 가능하며 옆에 살짝 보이는 부분을 클릭을 통하여 화면에 대한 이벤트도 적용할 수 있습니다.

이 포스트에서는 이벤트 적용에 대한 부분은 생략을 할 것입니다.
(자세한 내용은 참고 사이트를 참고해주세요.)

"카드뷰"의 핵심 기능은 pager.setPagemargin() 입니다.

setPageMargin() 을 활용하여 Pager의 margin 값을 음수로 이동 시 위와 같은 화면이 보여질 것입니다.

 

 

1. CarouselPagerAdapter

   Pager Adapter 부분으로 실질적으로 카드뷰 자체가 그려줄 때 설정하는 Adapter 입니다.

 

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
public class CarouselPagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
 
    private static final int FIRST_PAGE = 0;
    private Context context;
    private CarouselPagerLayout[] mRootLayout;
    private int mCount = 0;
    private List mImgList;
    public CarouselPagerAdapter(Context context, List list) {
        this.context = context;
        this.mImgList = list;
        mCount = mImgList.size();
        mRootLayout = new CarouselPagerLayout[list.size()];
    }
 
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        float scale =  MainActivity.BIG_SCALE;
 
        try {
            //First item change BigSize.
            if (position != FIRST_PAGE) {
                scale = MainActivity.SMALL_SCALE;
            }
 
            position = position % mImgList.size();
 
        } catch (Exception e) {
            // TODO: handle exception
        }
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.carouse_adapter_cell, null);
 
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        ImageView iv = Utils.findViewByIdFromView(view,R.id.img_pager,ImageView.class);
        iv.setLayoutParams(layoutParams);
        iv.setImageResource(mImgList.get(position));
        iv.setPadding(15151515);
 
        mImgList.get(position);
 
        mRootLayout[position] = (CarouselPagerLayout) view.findViewById(R.id.root);
        mRootLayout[position].setScaleValue(scale);
 
        container.addView(view, 0);
        return view;
    }
 
    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }
 
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        try {
            if (positionOffset >= 0f && positionOffset < 1f) {
                CarouselPagerLayout cur = getRootView(position);
                CarouselPagerLayout next = getRootView(position + 1);
 
                cur.setScaleValue(MainActivity.BIG_SCALE - MainActivity.DIFF_SCALE * positionOffset);
                next.setScaleValue(MainActivity.SMALL_SCALE + MainActivity.DIFF_SCALE * positionOffset);
 
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
 
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
       container.removeView((View) object);
    }
 
    @Override
    public void onPageSelected(int i) {
 
    }
 
    @Override
    public void onPageScrollStateChanged(int i) {
 
    }
 
    @Override
    public void finishUpdate(ViewGroup container) {
        super.finishUpdate(container);
    }
 
    @Override
    public int getCount() {
        if (mImgList != null) {
            return mImgList.size();
        }
        return 0;
    }
 
    /**
     * return 값에 따른 화면에 보여지는 결과가 달라진다.
     * @param view
     * @param o
     * @return
     */
    @Override
    public boolean isViewFromObject(View view, Object o) {
        return view == o;
    }
 
    private CarouselPagerLayout getRootView(int position){
        return mRootLayout[position];
    }
}
 
cs

 

 

2. CarouselPagerLayout 

  카드뷰의 Layout 을 표현하며, Canvas의 Scale 값을 변화하여 카드뷰의 크기를 조절합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
pupublic class CarouselPagerLayout extends LinearLayout {
    public CarouselPagerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public CarouselPagerLayout(Context context) {
        super(context);
    }
    private float scale = MainActivity.BIG_SCALE;
    public void setScaleValue(float scale){
        this.scale = scale;
        this.invalidate();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        int w = this.getWidth();
        int h = this.getHeight();
        canvas.scale(scale,scale,w/2,h/2);
        super.onDraw(canvas);
    }
}
 
 

ViewPager에서 사용할 View의 상태를 설정합니다.

 

 

3. MainActivity

  Pager을 호출하고 카드뷰의 값을 설정합니다.

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
public class MainActivity extends Activity {
 
    public static final float BIG_SCALE = 1.0f;
    public static final float SMALL_SCALE = 0.9f;
    public static final float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;
 
    CarouselPagerAdapter mAdapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        ViewPager pager;
        pager = Utils.findViewByIdFromActivity(this, R.id.pager1, ViewPager.class);
        mAdapter = new CarouselPagerAdapter(this, setListInfo());
        pager.setAdapter(mAdapter);
        pager.setPageMargin(-getPagerMarginValue());
        pager.addOnPageChangeListener(mAdapter);
        mAdapter.notifyDataSetChanged();
    }
 
    /**
     * Pager Margin 값을 설정한다.
     * @return
     * @throws Exception
     */
    private int getPagerMarginValue() {
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int pageMargin = (int) ((metrics.heightPixels / 9* 2); //중요! 이 부분을 조절하여 margin 설정 가능
        return pageMargin;
    }
 
    private List<Integer> setListInfo() {     
return Arrays.asList(R.drawable.lighthouse, R.drawable.penguins,R.drawable.tulips);
    }
}
 

 

 

4. activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<Linearlayout 
  xmlns:android="http://schemas.android.com/apk/res/android" 
  xmlns:tools="http://schemas.android.com/tools" 
  android:layout_width="match_parent"
  android:layout_height="match_parent" 
  android:orientation="vertical">
 
    <android.support.v4.view.Viewpager 
        android:id="@+id/pager1" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        android:overscrollmode="never">
</android.support.v4.view.Viewpager>
 
</Linearlayout >
 

 

5. carouse_adapter_cell.xml

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
<Linearlayout 
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:gravity="center" 
        android:paddingleft="20dp"
        android:paddingright="20dp" 
        android:orientation="vertical">
 
    <com.test.carouseexample.carouselpagerlayout 
        android:id="@+id/root" 
        android:layout_width="match_parent" 
        android:layout_height="match_parent" 
        android:background="@android:color/transparent" 
        android:gravity="center" 
        android:layout_margin="15dp" 
        android:orientation="vertical">
 
        <Framelayout 
            android:layout_width="match_parent" 
            android:layout_height="match_parent">
 
            <Linearlayout
                     android:layout_width="match_parent" 
                    android:layout_height="match_parent"
                    android:gravity="center" 
                    android:orientation="vertical">
 
                <Imageview 
                    android:id="@+id/img_pager" 
                    android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:padding="10dp">
 
                <Textview 
                    android:id="@+id/txt_context" 
                    android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:layout_gravity="center" 
                    android:layout_margintop="-50dp" 
                    android:gravity="center" 
                    android:text="" 
                    android:textcolor="#000" 
                    android:textsize="20dp">
                </Textview >
            </Linearlayout >
         </Framelayout>
     </com.testcarouseexample.carouselpagerlayout>
</Linearlayout >
 
 

 

Github에 오픈되어 있던 CarouselViewProject 을 참고하여 샘플 프로젝트로 만들어 공유 드렸습니다.

 

참고 

https://www.youtube.com/watch?v=b8nt-gqEfso

https://github.com/clkasd/CarouselViewProject/blob/master/src/net/infratek/CarouselView/MyPagerAdapter.java

https://colorscripter.com/ (소스 컬러 표현)

반응형
댓글