2014년 1월 27일 월요일

Fragment 에서 서버에서 받은 이미지로 무한 반복 드래그 ViewPager 구현.


Fragment 에서 서버에서 받은 이미지로 무한 반복 드래그 ViewPager 구현.

ViewPager는 드래그할 경우, 앞뒤 이미지를 생성해 둔 상태에서 동작한다. 따라서 무한 드래그구현시, 마지막 끝에서도 맨첫번째 이미지가 드래그 되도록 하기위해서, 이미 첫번째 이미지가 끝에 이어서 생성되어있어야 한다. 따라서, 프로그램상으로는 실제  view(여기선 이미지)에 사용하는 개수는 실재view의 개수의 3배로 설정한다. 

@Override public int getCount() { return (mProductCnt * 3); }

그리고, 
@Override public void onPageSelected(int position) {

 를 통해서, 적절하게 viewpager를 관리해 주면, 실제 view가 반복해서 무한으로 반복되도록 보일수 있게 할 수 있다.


이번 포스트에서의 또다른 포인트는,
ViewPager 무한 반복 드래그 구현시, TextView, LinearLayout등의 컴포넌트 구현시에는 문제가 되지 않지만, ImageView의 경우, 다시 반복되는 View가 나타날때 Exception 발생으로 문제가 되었었던 내용이있다.
해결을 위해, ImageView사용대신, Linearlayout을 대신 사용하였고, 서버에서 ImageView로 이미지를 받은 이유로, 
Drawable drawable = mImageArray.get(position).getDrawable();
            linearlayout.setBackgroundDrawable(drawable);
와 같은 코드를 추가하였다.

그리고, 서버에서 받은 이미지가 view에 표시되기까지 시간이 걸리므로, 
handler를 사용하여 약간의 딜레이를 주도록 하였다.


소스코드는 아래와 같다.



1. res-layout-xml 파일

1
2
3
4
<android.support.v4.view.ViewPager
    android:id="@+id/product_viewpager"
       android:layout_width="260dp"
       android:layout_height="124dp"/>



2. src-java파일

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
private ViewPager mProductPager;
 
 
public void init(ProductList plist) {
        mProductList = plist;
        mProductCnt = mProductList.getProductList().size();
        if(mProductCnt > 1) {
            mProductLeftArrow.setVisibility(View.VISIBLE);
            mProductRightArrow.setVisibility(View.VISIBLE);
        }
        
        mImageArray = new ArrayList<ImageView>();
        for(int i=0; i<mProductCnt; i++) {
            ImageView iv = new ImageView(mainActivity);
            //mainActivity.mResourceResolver.loadImage(new ImageHTTPGet(mProductList.getProductList().get(i).getIMAGE_URL()), iv);
            mImageArray.add(iv);
        }
 
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                ImagePagerAdapter pagerAdapter = new ImagePagerAdapter(mainActivity.getApplicationContext());
                mProductPager.setAdapter(pagerAdapter);
                mProductPager.setCurrentItem(mProductCnt);
                mProductPager.setOnPageChangeListener(new OnPageChangeListener() {
                    @Override public void onPageSelected(int position) {
                        if(position < mProductCnt){
                            //Logger.getInstance().log(TAG, "1 position+mProductCnt = " + (position+mProductCnt));
                            mProductPager.setCurrentItem(position+mProductCnt, false);
                        }
                        else if(position >= (mProductCnt*2)){
                            //Logger.getInstance().log(TAG, "2 position-mProductCnt = " + (position-mProductCnt));
                            mProductPager.setCurrentItem(position - mProductCnt, false);
                        }
                        else {
                            position -= mProductCnt;
                            mPrevPosition = position;
                            //Logger.getInstance().log(TAG, "3 mPrevPosition === " + mPrevPosition);
                        }
                        
                        mProductPage.setText(((position%mProductCnt)+1) + "/" + mProductCnt);
                    }
                    @Override public void onPageScrolled(int position, float positionOffest, int positionOffsetPixels) {}
                    @Override public void onPageScrollStateChanged(int state) {}
                });
                
                mPrevPosition = 0;
                int currNo = mPrevPosition + 1;
                mProductPage.setText(currNo + "/" + mProductCnt);
            }
        }, 500);
}
 
private class ImagePagerAdapter extends PagerAdapter{
        private Context mContext;
        public ImagePagerAdapter( Context con) { super(); mContext = con; }
 
        @Override public int getCount() { return (mProductCnt * 3); }
 
        @Override public Object instantiateItem(View pager, int position) 
        {
            position %= mProductCnt;
            final int pagerAdapterPosition = position;
 
            LinearLayout linearlayout = new LinearLayout(mContext);
            Drawable drawable = mImageArray.get(position).getDrawable();
            linearlayout.setBackgroundDrawable(drawable);
            Logger.getInstance().log(TAG, "1 pagerAdapterPosition = " + pagerAdapterPosition);
            
            linearlayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
//                    String uri = "http://m.amgbiz.firstmall.kr/goods/view?no=" + ;
                    //Logger.getInstance().log(TAG, "2 pagerAdapterPosition = " + pagerAdapterPosition);
                    //Logger.getInstance().log(TAG, "2 mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK() = " + mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK());
                    mainActivity.clickShopTab(mProductList.getProductList().get(pagerAdapterPosition).getGOODS_LINK());//pagerAdapterPosition 값이 보이는 이미지의 position보다 1이 더큼.
                }
            });
            
            ((ViewPager)pager).addView(linearlayout);
            return linearlayout;
        }
 
        @Override public void destroyItem(View pager, int position, Object view) {
            ((ViewPager)pager).removeView((View)view);
        }
 
        @Override public boolean isViewFromObject(View view, Object obj) { return view == obj; }
 
        @Override public void finishUpdate(View arg0) {}
        @Override public void restoreState(Parcelable arg0, ClassLoader arg1) {}
        @Override public Parcelable saveState() { return null; }
        @Override public void startUpdate(View arg0) {}
        @Override public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private ImageButton.OnClickListener onClick = new View.OnClickListener() {
        public void onClick(View v) {
            switch(v.getId()){
            case R.id.product_arrow_left:
                int pos = mProductPager.getCurrentItem();
                if(pos == 0 ) {
                    pos = mProductCnt - 1;
                } else {
                    pos --;
                }
                mProductPager.setCurrentItem(pos);
                break;
            case R.id.product_arrow_right:
                pos = mProductPager.getCurrentItem();
                if(pos == (mProductCnt - 1) ) {
                    pos = 0;
                } else {
                    pos ++;
                }
                mProductPager.setCurrentItem(pos);
                break;
                        }
        }
    };