본문 바로가기
Android

안드로이드 뷰페이져 인디케이터 사용해보기

by 일용직 코딩노동자 2023. 3. 29.
728x90
반응형

인디케이터는 배너광고같은 뷰페이져에 있어서 밑에 점처럼 생겨서 현재 몇번째 이미지를 보여주고있는지 보여주는 역할을 합니다.

이런식으로 밑에 검은 점같은게 보이나요?

 

이런식으로 표기해줄수있습니다.

 

프래그먼트에도 많이 사용하십니다.

 

우선 뷰를 그릴 클래스를 하나 추가하겠습니다.

 

class IndicatorView: LinearLayout {

    private var mContext: Context? = null
    private var mDefaultCircle: Int = 0
    private var mSelectCircle: Int = 0
    private var imageDot: MutableList<ImageView> = mutableListOf()

    private val temp = TypedValue.applyDimension(
        //점과 점 사이의 간격을 조절
        TypedValue.COMPLEX_UNIT_DIP, 4.0f, resources.displayMetrics)

    constructor(context: Context) : super(context) {
        mContext = context
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        mContext = context
    }

    fun createDotPanel(count: Int, defaultCircle: Int, selectCircle: Int, position: Int) {

        this.removeAllViews()

        mDefaultCircle = defaultCircle
        mSelectCircle = selectCircle

        for (i in 0 until count) {
            imageDot.add(ImageView(mContext).apply { setPadding(temp.toInt(), 0, temp.toInt(), 0) })
            this.addView(imageDot[i])
        }
        //인덱스 선택
        selectDot(position)
    }

    /**
     * 선택된 점 표시
     * @param position
     */
    fun selectDot(position: Int) {
        for (i in imageDot.indices) {
            if (i == position) {
                imageDot[i].setImageResource(mSelectCircle)
            }
            else {
                imageDot[i].setImageResource(mDefaultCircle)
            }
        }
    }
}

그리고 xml에 가셔서

 

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="168dp">
</androidx.viewpager.widget.ViewPager>

<패키지명.IndicatorView
    android:id="@+id/indicator"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
</패키지명.IndicatorView>

2개의 뷰를 추가해주시는데

 

뷰페이저는 적절한 위치에 놓아주시고 (본인 디자인에 맞게)

 

인디케이터는 뷰페이져와 겹쳐서 본인이 인디케이터를 보여주고싶은곳에 배치해주시면 됩니다.

 

그다음에 어댑터를 만들어줍니다.

어댑터는 코틀린이 아니라 자바인데 혼용해서 사용가능하니 걱정하지마세요.

 

public class ViewPagerAdapter extends PagerAdapter {
    private final String TAG = "로그 ";
    private Context mContext;
    private int mode;
    private ArrayList<String> imageList;

    public ViewPagerAdapter(Context context, ArrayList<String> imageList)
    {
        Log.d(TAG,"ViewPagerAdapter");
        this.mContext = context;
        this.imageList = imageList;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.viewpager_layout, null);

        ImageView imageView = view.findViewById(R.id.imageView);
        Glide.with(mContext)
                .load(imageList.get(position))
                .into(imageView);

        container.addView(view);

        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               ((뷰페이져가있는 클래스) mContext).viewPagerOnClick(position);
            }
        });

        return view;
    }

    @Override
    public int getCount() {
        return imageList.size();
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View)object);
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
        return (view == (View)o);
    }
}

viewPagerOnclick에서 에러가 나는분들은 메인으로 다시 오셔서

 

fun viewPagerOnClick(position : Int){
    Toast.makeText(this@본인클래스, position.toString() + "번째 배너광고 클릭", Toast.LENGTH_SHORT).show()
}

이렇게 하나 정의해주시면 됩니다.

 

본인뷰페이져.addOnPageChangeListener(object : ViewPager.OnPageChangeListener{
    override fun onPageScrollStateChanged(p0: Int) {

    }

    override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {

    }

    override fun onPageSelected(p0: Int) {
        xml에추가한 인디케이터.selectDot(p0)
    }
})

이렇게 리스너에 인디케이터를 박아주시면 됩니다.

 

val imageList = ArrayList<String>()

imageList.clear()
imageList?.add("이미지url") 

본인 인디케이터?.createDotPanel(imageList.count(), R.drawable.indicator_dot_off, R.drawable.indicator_dot_on, 0)
본인 뷰페이져?.setClipToPadding(false)

val density = resources.displayMetrics.density
val margin = (0 * density).toInt()
본인 뷰페이져?.setPadding(margin, 0, margin, 0)
본인 뷰페이져?.setPageMargin(margin / 2)

본인 뷰페이져?.setAdapter(ViewPagerAdapter(context,imageList))

drawable같은곳에 있는 이미지를 보여주고싶으시면 imageList를 int형으로 선언하셔서 add하실때

R.id.이미지파일명 으로 add 하시면됩니다.

 

그리고 저는 자동으로 뷰페이져를 움직이게 하기위해서

 

fun autoViewPager(){
    timer(period = 3000){
        runOnUiThread{
            var position = 본인 뷰페이져?.currentItem ?: 0
            if(본인 뷰페이져?.currentItem == imageList.count() - 1) position = 0
            else position++
            본인 뷰페이져?.setCurrentItem(position,true)
        }
    }
}

함수를 하나 정의했고 setAdapter할때 같이 선언해줬습니다.

여기까지 하시면 뷰페이져에 인디케이터 넣기 성공입니다.

728x90
반응형

댓글