안드로이드 ui 학습 시리즈 - 사용자 정의 Behavior(3) - 보기 페이지
이번의 예는 다음과 같다.
내가 이룬 효과:
ezgif.com-video-to-gif.gif
어떻게 스크롤 수치를 소비하고 미끄럼 방향을 판단합니까
이번 예를 배우기 전에 중요한 것이 하나 있는데 그것이 바로 미끄럼의 방향을 어떻게 판단하는가이다. 여기서 우리는 이 두 가지 방법을 중점적으로 살펴보자.
/**
*
* @param coordinatorLayout
* @param child
* @param target
* @param dxConsumed target x
* @param dyConsumed target y
* @param dxUnconsumed x
* @param dyUnconsumed y
*/
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
/**
*
* nested scroll child , nested scroll child
* onNestedPreScroll。 consumed,
* 。 100px,child 90px , consumed[1] 90,
* coordinatorLayout 10px 。
* @param coordinatorLayout
* @param child
* @param target
* @param dx
* @param dy
* @param consumed
*/
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
여러분이 onNested PreScroll과 onNested Scroll에 대해 얼마나 많은 인상을 가지고 있는지 모르겠습니다. 이 두 가지 방법은 핵심 방법입니다. 이 두 가지 방법 중에서 우리는 스크롤 이벤트를 소비할 수 있습니다.
두 가지 방법 중 중요한 매개변수는 다음과 같습니다.
if (dyConsumed > 0 && dyUnconsumed == 0) {
System.out.println(" 。。。");
}
if (dyConsumed == 0 && dyUnconsumed > 0) {
System.out.println(" 。。。");
}
if (dyConsumed < 0 && dyUnconsumed == 0) {
System.out.println(" 。。。");
}
if (dyConsumed == 0 && dyUnconsumed < 0) {
System.out.println(" , 。。。");
}
이렇게 하면 우리는 스크롤 방향과 스크롤 컨트롤러가 끝까지 굴러갔는지 판단할 수 있다.컨트롤러가 머리를 굴릴 때 손가락이 계속 미끄러질 수 있다. 이때 스크롤 이벤트는 여전히 발생하고 있다. 단지 더 이상 컨트롤러에 의해 소비되지 않을 뿐이다.
사고의 방향을 분석하다.
위의 방법 사용, 매개 변수의 의미를 보면 우리는 이번 예를 완성할 수 있다.
논리에 따라 두 개의 사고 단락으로 나뉜다.
@Override
public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
mViewHead = parent.findViewById(R.id.kaiyan_appbar);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
if (layoutParams != null && layoutParams.height == CoordinatorLayout.LayoutParams.MATCH_PARENT) {
child.layout(0, 0, layoutParams.width, layoutParams.height);
child.setTranslationY(getAppBarHeight());
}
return super.onLayoutChild(parent, child, layoutDirection);
}
슬라이딩
슬라이딩을 할 때 우리는 목록을 스크롤하지 않고 위로 이동하여 헤드를 가려야 하기 때문에 스크롤 컨트롤을 하기 전에 스크롤 데이터를 소비해야 하기 때문에 onNested PreScroll이라는 방법에서 조작을 선택했다. 코드는 다음과 같다.
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
// , , , , ,
float translationY = child.getTranslationY();
float offsetaAlphe = 0;
if (dy > 0 && translationY > 0) {
//
float offestY = translationY - dy;
Log.d("AAA", "translationY:" + translationY + " / dy:" + dy);
if (offestY < 0) {
// Y ,
Log.d("AAA", "AAA");
offestY = 0;
consumed[1] = (int) translationY;
} else {
Log.d("AAA", "BBB:");
offestY = translationY - dy;
consumed[1] = dy;
}
Log.d("AAA", "translationY:" + offestY);
child.setTranslationY(offestY);
//
if (mViewHead != null) {
offsetaAlphe = 0.5f + 0.5f * (translationY / getAppBarHeight());
mViewHead.setAlpha(offsetaAlphe);
}
}
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
아이디어:
하강시
미끄러질 때 우리는 목록을 스크롤하지 않고 아래로 이동하고 헤드를 노출해야 한다. 이것은 위의 어느 함수에 쓸 수 없다. 모두가 생각하기에 목록이 머리를 스크롤할 수 있고 더 이상 위로 스크롤할 수 없기 때문에 헤드를 드러내야 한다. 그래서 onNested Scroll이라는 방법에서 조작한다. 코드는 다음과 같다.
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
int appBarHeight = getAppBarHeight();
float offestY = 0;
float translationY = child.getTranslationY();
float offsetaAlphe = 0;
if (dyUnconsumed < 0 && translationY < appBarHeight) {
//
offestY = translationY + Math.abs(dyUnconsumed);
if (offestY < 0) {
offestY = 0;
}
if (offestY >= appBarHeight) {
offestY = appBarHeight;
}
child.setTranslationY(offestY);
//
if (mViewHead != null) {
if (translationY > appBarHeight) {
translationY = appBarHeight;
}
offsetaAlphe = 0.5f + 0.5f * (translationY / getAppBarHeight());
mViewHead.setAlpha(offsetaAlphe);
}
}
}
사고방식은 위의 것과 많이 다르지 않아서 너무 상세하게 말하지 않는다.
모든 코드:
public class KaiYanAppBarBehavior extends CoordinatorLayout.Behavior {
private Context mContext;
private View mViewHead;
private int appbarHeight = 0;
public KaiYanAppBarBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
@Override
public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
mViewHead = parent.findViewById(R.id.kaiyan_appbar);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
if (layoutParams != null && layoutParams.height == CoordinatorLayout.LayoutParams.MATCH_PARENT) {
child.layout(0, 0, layoutParams.width, layoutParams.height);
child.setTranslationY(getAppBarHeight());
}
return super.onLayoutChild(parent, child, layoutDirection);
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
// , , , , ,
float translationY = child.getTranslationY();
float offsetaAlphe = 0;
if (dy > 0 && translationY > 0) {
//
float offestY = translationY - dy;
Log.d("AAA", "translationY:" + translationY + " / dy:" + dy);
if (offestY < 0) {
// Y ,
Log.d("AAA", "AAA");
offestY = 0;
consumed[1] = (int) translationY;
} else {
Log.d("AAA", "BBB:");
offestY = translationY - dy;
consumed[1] = dy;
}
Log.d("AAA", "translationY:" + offestY);
child.setTranslationY(offestY);
//
if (mViewHead != null) {
offsetaAlphe = 0.5f + 0.5f * (translationY / getAppBarHeight());
mViewHead.setAlpha(offsetaAlphe);
}
}
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
int appBarHeight = getAppBarHeight();
float offestY = 0;
float translationY = child.getTranslationY();
float offsetaAlphe = 0;
if (dyUnconsumed < 0 && translationY < appBarHeight) {
//
offestY = translationY + Math.abs(dyUnconsumed);
if (offestY < 0) {
offestY = 0;
}
if (offestY >= appBarHeight) {
offestY = appBarHeight;
}
child.setTranslationY(offestY);
//
if (mViewHead != null) {
if (translationY > appBarHeight) {
translationY = appBarHeight;
}
offsetaAlphe = 0.5f + 0.5f * (translationY / getAppBarHeight());
mViewHead.setAlpha(offsetaAlphe);
}
}
}
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
Log.d("AAA", "onNestedPreFling:" + velocityY);
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
private int getAppBarHeight() {
if (appbarHeight == 0) {
if (mViewHead == null) {
return appbarHeight;
}
appbarHeight = mViewHead.getMeasuredHeight();
if (appbarHeight == 0) {
mViewHead.measure(0, 0);
appbarHeight = mViewHead.getMeasuredHeight();
}
}
return appbarHeight;
// return mContext.getResources().getDimensionPixelOffset(R.dimen.app_bar_height);
}
}
마지막
여기서 우리는 몇 가지를 알아야 한다. 매우 중요하다.
참조 자료:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.