Android 는 ViewPager 를 이용 하여 미끄럼 확대 및 축소 갤러리 효 과 를 실현 합 니 다.
이 예 는 제 가 괜 찮 을 때 쓴 작은 항목 입 니 다.구체 적 인 소스 주 소 는 방문 하 십시오https://github.com/AlexSmille/YingMi
이 갤러리 는 표지 와 비슷 한 효과 로 중간 으로 미 끄 러 지 는 그림 이 점점 커지 고 떠 나 는 View 는 점점 줄 어 들 며 미끄럼 감청 과 클릭 감청 을 설정 할 수 있다.
인터넷 에 서 는 Gallery 를 통 해 이 루어 진 사례 가 많 습 니 다.상례 의 실현 은 ViewPager 를 통 해 이 루어 진 것 으로 성능 최적화 문 제 를 해결 하 였 습 니 다.오늘 은 특별히 이 를 뽑 아서 포장 하여 앞으로 편리 하 게 사용 할 수 있 도록 하 겠 습 니 다.최종 실현 효 과 는 다음 과 같다.
사용 방식
레이아웃 에 사용자 정의 컨트롤 추가
<RelativeLayout 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">
<!-- -->
<com.mahao.alex.customviewdemo.viewpager.CoverFlowViewPager
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
코드 설정코드 의 설정 은 다음 과 같은 몇 가지 절차 로 나 뉜 다.
•찾기 컨트롤
•데이터 초기 화
•표시 할 데 이 터 를 컨트롤 에 설정 합 니 다.
•미끄럼 감청 설정
public class MainActivity extends AppCompatActivity {
private CoverFlowViewPager mCover;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCover = (CoverFlowViewPager) findViewById(R.id.cover);
//
List<View> list = new ArrayList<>();
for(int i = 0;i<10;i++){
ImageView img = new ImageView(this);
img.setBackgroundColor(Color.parseColor("#"+getRandColorCode()));
list.add(img);
}
//
mCover.setViewList(list);
// ,
mCover.setOnPageSelectListener(new OnPageSelectListener() {
@Override
public void select(int position) {
Toast.makeText(getApplicationContext(),position+"",Toast.LENGTH_SHORT).show();
}
});
}
/**
* ,
* @return
*/
public static String getRandColorCode(){
String r,g,b;
Random random = new Random();
r = Integer.toHexString(random.nextInt(256)).toUpperCase();
g = Integer.toHexString(random.nextInt(256)).toUpperCase();
b = Integer.toHexString(random.nextInt(256)).toUpperCase();
r = r.length()==1 ? "0" + r : r ;
g = g.length()==1 ? "0" + g : g ;
b = b.length()==1 ? "0" + b : b ;
return r+g+b;
}
}
실현 원리실현 과정 에서 두 가지 난점 이 있다.
•어떻게 미끄럼 과정 중의 확대 와 축 소 를 실현 합 니까?
•ViewPager 에 표시 되 지 않 은 페이지 를 표시 하 는 방법
어떻게 미끄럼 과정 중의 확대 와 축 소 를 실현 합 니까?
모든 ViewPager 의 페이지 를 설정 할 때 모든 페이지 에 고정 적 인 padding 값 을 설정 하면 모든 페이지 가 축소 상 태 를 표시 합 니 다.이 동시에 ViewPager 는 addOnPageChangeListener()를 설정 하고 슬라이딩 감청 을 하 며 이 슬라이딩 감청 에 서 는 ViewPager 가 미 끄 러 지 는 상태,미 끄 러 지 는 편 이 량 등 을 되 돌려 미 끄 러 지 는 편 이 량 에 따라 확대 축소 합 니 다.padding 값 에 따라 컨트롤 의 디 스 플레이 크기 를 설정 합 니 다.
ViewPager 에 표시 되 지 않 은 페이지 를 표시 하 는 방법
xml 에 자주 사용 되 지 않 는 속성 android:clipChildren 이 있 습 니 다.하위 View 의 표 시 를 제한 할 지 여부 입 니 다.false 로 설정 하면 하위 View 의 디 스 플레이 는 부모 컨트롤 의 제한 을 받 지 않 습 니 다.
코드 구현
컨트롤 의 레이아웃 파일 을 작성 합 니 다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false">
<android.support.v4.view.ViewPager
android:id="@+id/vp_conver_flow"
android:layout_width="180dp"
android:layout_height="260dp"
android:layout_centerHorizontal="true"
android:clipChildren="false" />
</RelativeLayout>
상대 레이아웃 에 ViewPager 를 삽입 합 니 다.상대 레이아웃 은 표시 범 위 를 확인 하 는 데 사 용 됩 니 다.ViewPager 는 미끄럼,확대 축소 등 을 실현 합 니 다.CoverFlowViewPager 를 만 들 고 레이아웃 을 불 러 옵 니 다.
/**
*
*
* Created by alex_mahao on 2016/8/25.
*/
public class CoverFlowViewPager extends RelativeLayout implements OnPageSelectListener {
/**
*
*/
private ViewPager mViewPager;
public CoverFlowViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
inflate(context, R.layout.widget_cover_flow,this);
mViewPager = (ViewPager) findViewById(R.id.vp_conver_flow);
//init();
}
컨트롤 을 찾 고 레이아웃 을 불 러 옵 니 다.어댑터 를 작성 하여 미 끄 러 지 는 감청 을 실현 합 니 다.
ViewPager 가 생 겼 으 니 어댑터 Adapter 가 있어 야 합 니 다.미끄럼 감청 에서 각 하위 요 소 를 오프셋 에 따라 조작 하고 확대 하거나 축소 해 야 하기 때문에 하위 요 소 는 물론 어댑터 가 가장 쉽게 얻 을 수 있 기 때문에 Adapter 를 ViewPager 의 미끄럼 감청 인 터 페 이 스 를 실현 합 니 다.
/**
*
* Created by alex_mahao on 2016/8/25.
*/
public class CoverFlowAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
/**
* padding
*/
public static int sWidthPadding;
public static int sHeightPadding;
/**
*
*/
private List<View> mViewList;
/**
*
*/
private OnPageSelectListener listener;
/**
*
*/
private Context mContext;
public CoverFlowAdapter(List<View> mImageViewList, Context context) {
this.mViewList = mImageViewList;
mContext = context;
// padding
sWidthPadding = dp2px(24);
sHeightPadding = dp2px(32);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mViewList.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = mViewList.get(position);
container.addView(view);
return view;
}
@Override
public int getCount() {
return mViewList == null ? 0 : mViewList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// ViewPager
if (mViewList.size() > 0 && position < mViewList.size()) {
// , 0 1 offset ,padding
Log.i("info", " padding");
int outHeightPadding = (int) (positionOffset * sHeightPadding);
int outWidthPadding = (int) (positionOffset * sWidthPadding);
// 0 , position = 0, ,
mViewList.get(position).setPadding(outWidthPadding, outHeightPadding, outWidthPadding, outHeightPadding);
// position+1 ,
if (position < mViewList.size() - 1) {
int inWidthPadding = (int) ((1 - positionOffset) * sWidthPadding);
int inHeightPadding = (int) ((1 - positionOffset) * sHeightPadding);
mViewList.get(position + 1).setPadding(inWidthPadding, inHeightPadding, inWidthPadding, inHeightPadding);
}
}
}
@Override
public void onPageSelected(int position) {
//
if (listener != null) {
listener.select(position);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
/**
*
*
* @param listener
*/
public void setOnPageSelectListener(OnPageSelectListener listener) {
this.listener = listener;
}
/**
* dp px
*
* @param dp
* @return
*/
public int dp2px(int dp) {
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources().getDisplayMetrics());
return px;
}
}
코드 변경 은 두 부분 으로 나 뉘 는데 PagerAdapter 가 이 루어 지고 미끄럼 감청 이 이 루어 집 니 다.Pager Adapter 의 실현 은 더 이상 말 하지 않 고 가장 기본 적 인 것 이다.미끄럼 감청 의 실현 에 중점 을 두다.미끄럼 감청 에는 세 가지 반전 방법 이 있 습 니 다.그 중에서 onPage Scrolled(int position,float position Offset,int position Offset Pixels)는 ViewPager 의 미끄럼 오프셋 입 니 다.저 희 는 해당 요소 의 padding 값 을 다시 동적 으로 설정 하여 확대 축 소 를 실현 합 니 다.
onPageSelected()는 선택 한 반전 을 위해 사용자 정의 인터페이스 방식 으로 호출 자 에 게 되 돌려 줍 니 다.나중에 얘 기 할 게 요.
ViewPager 초기 화
어댑터 가 생 겼 으 니 자 연 스 럽 게 어댑터 부분 을 만 들 기 시작 합 니 다.
/**
*
*/
private void init() {
// ,
mAdapter = new CoverFlowAdapter(mViewList,getContext());
//
mAdapter.setOnPageSelectListener(this);
//
mViewPager.setAdapter(mAdapter);
// , adpter , adpter
mViewPager.addOnPageChangeListener(mAdapter);
//
mViewPager.setOffscreenPageLimit(5);
//
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// ViewPager
return mViewPager.dispatchTouchEvent(event);
}
});
}
주석 은 매우 상세 하 며,유일 하 게 설명 해 야 할 것 은 사건 의 배포 이다.우리 의 ViewPager 의 크기 는 고정 되 어 있 고 중간 에 있 는 디 스 플레이 영역 만 있 습 니 다.그러면 손가락 이 두 측면 에서 미 끄 러 질 때 ViewPager 는 터치 사건 을 자 연 스 럽 게 받 아들 이지 못 합 니 다.바깥쪽 의 상대 적 인 레이아웃 을 설정 한 터치 사건 감청 을 통 해 터치 사건 을 ViewPager 에 전달 하고 ViewPager 이외 의 지역 을 실제 적 으로 미 끄 러 질 때 ViewPager 는 해당 하 는 미끄럼 을 실현 할 수 있 습 니 다.
데이터 원본 포장
어댑터 가 있 습 니 다.ViewPager 도 있 습 니 다.그러면 데이터 원본 만 남 았 습 니 다.
우 리 는 padding 값 설정 에 따라 이 루어 집 니 다.표시 할 컨트롤 에 대해 서 는 배경 이 확대 되 지 않 기 때문에 컨트롤 에 대해 외부 컨트롤 을 포장 합 니 다.이렇게 외부 컨트롤 의 padding 값 을 설정 하면 자 연 스 럽 게 표시 해 야 할 컨트롤 이 확대 되 고 축 소 됩 니 다.
/**
* ,
* @param lists
*/
public void setViewList(List<View> lists){
if(lists==null){
return;
}
mViewList.clear();
for(View view:lists){
FrameLayout layout = new FrameLayout(getContext());
// padding ,
layout.setPadding(CoverFlowAdapter.sWidthPadding,CoverFlowAdapter.sHeightPadding,CoverFlowAdapter.sWidthPadding,CoverFlowAdapter.sHeightPadding);
layout.addView(view);
mViewList.add(layout);
}
//
mAdapter.notifyDataSetChanged();
}
감청 반전 선택우리 가 미 끄 러 질 때,미 끄 러 짐 에 따라 다른 데 이 터 를 표시 할 수 있 습 니 다.
미끄럼 감청 설정 을 통 해 onPageSelected 에 대해 층 층 의 인터페이스 리 셋 을 실현 합 니 다.
인터페이스의 정의 OnPageSelectListener
public interface OnPageSelectListener {
void select(int position);
}
CoverFlowAdapter 에 리 셋 추가
@Override
public void onPageSelected(int position) {
//
if (listener != null) {
listener.select(position);
}
}
CoverFlowViewPager 에 리 셋 추가
//
@Override
public void select(int position) {
if(listener!=null){
listener.select(position);
}
}
이벤트 설정 클릭데이터 원본 순환 에 대한 감청 을 직접 설정 하면 됩 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.