一、可行性分析

滑盖布局应用非常广泛,HorizontalScrollView本身实现的滑动效果让实现变得很简单。

e88435f4fd55dba42267c777979ecf73.gif

二、代码实现

public class SlidingFoldLayout extends HorizontalScrollView {

private TextPaint mPaint = null;

private LinearLayout mWrapperView = null;

private boolean isFirstLayout = true;

private float maskAlpha = 1.0f;

public SlidingFoldLayout(Context context) {

this(context, null);

}

public SlidingFoldLayout(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public SlidingFoldLayout(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

LinearLayout linearLayout = getWrapperLayout(context);

setOverScrollMode(View.OVER_SCROLL_NEVER);

setWillNotDraw(false);

mPaint = createPaint();

addViewInLayout(linearLayout, 0, linearLayout.getLayoutParams(), true);

mWrapperView = linearLayout;

}

public LinearLayout getWrapperLayout(Context context) {

LinearLayout linearLayout = new LinearLayout(context);

HorizontalScrollView.LayoutParams lp = generateDefaultLayoutParams();

lp.width = LayoutParams.WRAP_CONTENT;

linearLayout.setLayoutParams(lp);

linearLayout.setOrientation(LinearLayout.HORIZONTAL);

linearLayout.setPadding(0, 0, 0, 0);

return linearLayout;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int childCount = mWrapperView.getChildCount();

if (childCount == 0) {

return;

}

int leftMenuWidth = mWrapperView.getChildAt(0).getMeasuredWidth();

ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams();

int width = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();

if (lp instanceof ViewGroup.MarginLayoutParams) {

width = width - ((MarginLayoutParams) lp).leftMargin - ((MarginLayoutParams) lp).rightMargin;

}

if (width <= leftMenuWidth) {

mWrapperView.getChildAt(0).getLayoutParams().width = (int) (width - dp2px(50));

measureChild(mWrapperView, widthMeasureSpec, heightMeasureSpec);

}

if (childCount != 2) {

return;

}

View rightView = mWrapperView.getChildAt(1);

int rightMenuWidth = rightView.getMeasuredWidth();

if (width != rightMenuWidth) {

rightView.getLayoutParams().width = width;

measureChild(mWrapperView, widthMeasureSpec, heightMeasureSpec);

rightView.bringToFront();

}

}

private float dp2px(int dp) {

return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());

}

@Override

public void addView(View child) {

int childCount = mWrapperView.getChildCount();

if (childCount > 2) {

throw new IllegalStateException("SlidingFoldLayout should host only two child");

}

ViewGroup.LayoutParams lp = child.getLayoutParams();

if (lp != null && lp instanceof LinearLayout.LayoutParams) {

lp = new LinearLayout.LayoutParams(lp);

child.setLayoutParams(lp);

}

mWrapperView.addView(child);

}

public int getRealChildCount() {

if (mWrapperView == null) {

return 0;

}

return mWrapperView.getChildCount();

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

if(isFirstLayout && getRealChildCount()==2){

View leftView = mWrapperView.getChildAt(0);

scrollTo(leftView.getWidth(),0);

}

isFirstLayout = true;

}

@Override

protected void onScrollChanged(int l, int t, int oldl, int oldt) {

super.onScrollChanged(l, t, oldl, oldt);

int realCount = getRealChildCount();

if(realCount!=2) return;

View leftView = mWrapperView.getChildAt(0);

leftView.layout(l,t,l+leftView.getWidth(),t+leftView.getHeight());

maskAlpha = leftView.getLeft()*1.0f/leftView.getWidth();

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

int action = ev.getAction();

switch (action){

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

case MotionEvent.ACTION_OUTSIDE:

super.onTouchEvent(ev);

scrollToTraget();

break;

}

return super.onTouchEvent(ev);

}

private void scrollToTraget() {

int count = getRealChildCount();

if(count!=2) return;

int with = getWidth();

if(with==0) return;

View leftView = mWrapperView.getChildAt(0);

float x = leftView.getLeft()*1.0f/leftView.getWidth();

if(x > 0.5f){

smoothScrollTo(leftView.getWidth(),0);

}else{

smoothScrollTo(0,0);

}

}

@Override

public void addView(View child, int index) {

int childCount = mWrapperView.getChildCount();

if (childCount > 2) {

throw new IllegalStateException("SlidingFoldLayout should host only two child");

}

ViewGroup.LayoutParams lp = child.getLayoutParams();

if (lp != null && lp instanceof LinearLayout.LayoutParams) {

lp = new LinearLayout.LayoutParams(lp);

child.setLayoutParams(lp);

}

mWrapperView.addView(child, index);

}

@Override

public void addView(View child, ViewGroup.LayoutParams params) {

int childCount = mWrapperView.getChildCount();

if (childCount > 2) {

throw new IllegalStateException("SlidingFoldLayout should host only two child");

}

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(params);

child.setLayoutParams(lp);

mWrapperView.addView(child, lp);

}

@Override

public void addView(View child, int index, ViewGroup.LayoutParams params) {

int childCount = mWrapperView.getChildCount();

if (childCount > 2) {

throw new IllegalStateException("SlidingFoldLayout should host only two child");

}

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(params);

child.setLayoutParams(lp);

mWrapperView.addView(child, index);

}

private TextPaint createPaint() {

// 实例化画笔并打开抗锯齿

TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);

paint.setAntiAlias(true);

return paint;

}

@Override

protected void dispatchDraw(Canvas canvas) {

super.dispatchDraw(canvas);

int realCount = getRealChildCount();

if(realCount!=2) return;

View leftView = mWrapperView.getChildAt(0);

View rightView = mWrapperView.getChildAt(1);

RectF rectF = new RectF();

rectF.top = leftView.getTop();

rectF.bottom = leftView.getBottom();

rectF.left = leftView.getLeft();

rectF.right = rightView.getLeft();

int alpha = (int) (153*maskAlpha);

mPaint.setColor(argb(alpha,0x00,0x00,0x00));

int saveId = canvas.save();

canvas.drawRect(rectF,mPaint);

canvas.restoreToCount(saveId);

}

public static int argb(

int alpha,

int red,

int green,

int blue) {

return (alpha << 24) | (red << 16) | (green << 8) | blue;

}

}

三、使用方式

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="300dp"

android:layout_height="match_parent"

android:gravity="center"

>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scaleType="centerCrop"

android:src="@mipmap/img_sample_text"

/>

android:layout_width="500dp"

android:layout_height="match_parent"

android:background="@color/colorAccent"

>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:scaleType="fitCenter"

android:src="@mipmap/img_sample_panda"

/>

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐