반응형
https://ehdnsdlek.tistory.com/31
저번 게시글에는 ViewPager2를 이용해서 자동으로 Slide 되게끔 만들어 보았습니다.
거기에 추가로 좌측 하단에 Indicator를 만들어 보겠습니다
1. customView를 만들기 위해 클래스 만들기
기초 코드는 https://black-jin0427.tistory.com/95 여기서 가져왔습니다.
// CircleIndicator.java
public class CircleIndicator extends LinearLayout {
private Context mContext;
private int mDefaultCircle;
private int mSelectCircle;
private List<ImageView> imageDot = new ArrayList<>();
// 4.5dp를 픽셀 단위로 바꿉니다.
private final float temp = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 4.5f, getResources().getDisplayMetrics());
public CircleIndicator(Context context) {
super(context);
mContext = context;
}
public CircleIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
/**
* 기본 점 생성
* @param count 점의 갯수
* @param defaultCircle 기본 점의 이미지
* @param selectCircle 선택된 점의 이미지
* @param position 선택된 점의 포지션
*/
public void createDotPanel(int count, int defaultCircle, int selectCircle, int position) {
this.removeAllViews();
mDefaultCircle = defaultCircle;
mSelectCircle = selectCircle;
for (int i = 0; i < count; i++) {
ImageView dot = new ImageView(mContext);
dot.setPadding((int) temp, 0, (int) temp, 0);
imageDot.add(dot);
this.addView(dot);
}
// 인덱스 선택
selectDot(position);
}
/**
* 선택된 점 표시
* @param position
*/
public void selectDot(int position) {
for (int i = 0; i < imageDot.size(); i++) {
if (i == position) {
imageDot.get(i).setImageResource(mSelectCircle);
} else {
imageDot.get(i).setImageResource(mDefaultCircle);
}
}
}
}
2. CustomView 추가하기
자신의 패키지 이름에 맞춰서 코드를 수정해서 사용하시면 됩니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/slideViewPager"
android:layout_width="match_parent"
android:layout_height="220dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.example.toptoon.CircleIndicator // 자신의 패키지에 맞게 수정하기
android:id="@+id/slideIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="@id/slideViewPager"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
3. Indicator 레이아웃 작성하기
res/drawable 폴더에 생성하시면 됩니다.
// indicator_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/red" /> <!-- 주황색 지정 -->
<size android:width="20dp"
android:height="10dp"/>
</shape>
// indicator_unselected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/gray" /> <!-- 회색 지정 -->
<size android:width="10dp"
android:height="10dp"/>
</shape>
4. ViewPager2와 Indicator 연결하기
CircleIndicator의 createDotPanel 메소드를 사용해서 인디케이터를 초기화 합니다.
여기서 인디케이터 점의 수(imagesLength)와 drawable 리소스를 지정합니다.
또한 ViewPager2에 어댑터를 설정해주어야 합니다. SlideImageAdapter 인스턴스를 생성하고,
slideViewPager.setAdapter(adapter)를 통해 ViewPager2에 설정합니다.
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
SlideImageAdapter adapter = new SlideImageAdapter(getContext());
slideViewPager = binding.slideViewPager;
slideViewPager.setAdapter(adapter);
int imagesLength = adapter.getImageArrayLength(); // 이미지 개수 가져오기
// 인디케이터 초기화
CircleIndicator circleIndicator = binding.slideIndicator;
// 실제 이미지 수에 맞게 점 개수를 조정
circleIndicator.createDotPanel(imagesLength, R.drawable.indicator_unselected, R.drawable.indicator_selected, 0);
slideViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
// 실제 페이지 인덱스를 계산합니다.
// 무한 스크롤을 구현하는 경우가 아니라면, position을 직접 사용할 수 있습니다.
int realPosition = position % slideViewPager.getAdapter().getItemCount();
// 선택된 페이지에 해당하는 인디케이터 점을 강조 표시합니다.
circleIndicator.selectDot(realPosition);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// 스크롤 중 이벤트를 처리할 필요가 있다면 여기에 로직을 추가합니다.
}
@Override
public void onPageScrollStateChanged(int state) {
// 페이지 스크롤 상태 변경 이벤트를 처리할 필요가 있다면 여기에 로직을 추가합니다.
}
});
return binding.getRoot();
}
}
반응형
'Android' 카테고리의 다른 글
[Android] ViewPager2에 관련된 속성들 (0) | 2024.05.03 |
---|---|
[Android] String Resources - <string-array>로 깔끔하게 관리하자 (0) | 2024.04.02 |
[Android] ViewPager2 - Runnable 객체로 자동으로 이미지 slide 하기 (1) | 2024.03.17 |
[Android] View의 LifeCycle(생명주기) (0) | 2024.03.16 |
[Android] Fragment에서 Binding 객체를 null로 설정해야 하는 이유 (1) | 2024.03.15 |