Android 몰입 형 상태 표시 줄+actionBar 그 라 데 이 션+scrollView 상단 신축 효과

잡담 은 그만 하고 바로 그림 을 그리다.

제 프로 그래 밍 사상 을 말씀 드 리 겠 습 니 다.
첫 번 째 부분:몰입 형 상태 표시 줄(API-Level 19,Android 4.4 KitKat 이후 추 가 된 것),그리고 API-Level 21 버 전에 속성 이 추가 되 었 습 니 다.그래서 스타일 파일 은 세 부 를 설명해 야 합 니 다.
values

<style name="TranslucentTheme" parent="@style/AppTheme">
</style>
values-19

<style name="TranslucentTheme" parent="@style/AppTheme">
 <item name="android:windowTranslucentStatus">true</item>
 <item name="android:windowTranslucentNavigation">false</item>
</style>
values-V21

<style name="TranslucentTheme" parent="@style/AppTheme">
 <item name="android:windowTranslucentStatus">true</item>
 <item name="android:windowTranslucentNavigation">false</item>
 <!-- v-21        -->
 <item name="android:statusBarColor">@android:color/transparent</item>
</style>
이상 속성의 의미 와 사용 방식 에 대해 서 는 설명 을 많이 하지 않 습 니 다.상세 참조 가능https://www.jb51.net/article/104485.htm
두 번 째 부분:actionBar 그 라 데 이 션
actionBar 그 라 데 이 션 을 실현 해 야 하기 때문에 시스템 의 actionBar 를 사용 하지 않 았 습 니 다.LinearLayout 에서 계승 할 View Group 을 사용자 정의 한 것 입 니 다.
코드 를 바로 보 여 드릴 게 요.

package test.com.widget; 
import android.content.Context; 
import android.text.TextUtils; 
import android.util.AttributeSet; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import test.com.R; 
import test.com.impl.ActionBarClickListener; 
/** 
 *       actionBar 
 * Created by   (Milo) on 2016/12/28. 
 * email:[email protected] 
 */ 
public final class TranslucentActionBar extends LinearLayout { 
 private View layRoot; 
 private View vStatusBar; 
 private View layLeft; 
 private View layRight; 
 public TextView tvTitle; 
 private TextView tvLeft; 
 private TextView tvRight; 
 private View iconLeft; 
 private View iconRight; 
 public TranslucentActionBar(Context context) { 
  this(context, null); 
 } 
 public TranslucentActionBar(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  init(); 
 } 
 public TranslucentActionBar(Context context, AttributeSet attrs, int defStyleAttr) { 
  super(context, attrs, defStyleAttr); 
 } 
 private void init() { 
  setOrientation(HORIZONTAL); 
  View contentView = inflate(getContext(), R.layout.actionbar_trans, this); 
  layRoot = contentView.findViewById(R.id.lay_transroot); 
  vStatusBar = contentView.findViewById(R.id.v_statusbar); 
  tvTitle = (TextView) contentView.findViewById(R.id.tv_actionbar_title); 
  tvLeft = (TextView) contentView.findViewById(R.id.tv_actionbar_left); 
  tvRight = (TextView) contentView.findViewById(R.id.tv_actionbar_right); 
  iconLeft = contentView.findViewById(R.id.iv_actionbar_left); 
  iconRight = contentView.findViewById(R.id.v_actionbar_right); 
 } 
 /** 
  *         
  * 
  * @param statusBarHeight 
  */ 
 public void setStatusBarHeight(int statusBarHeight) { 
  ViewGroup.LayoutParams params = vStatusBar.getLayoutParams(); 
  params.height = statusBarHeight; 
  vStatusBar.setLayoutParams(params); 
 } 
 /** 
  *          
  */ 
 public void setNeedTranslucent() { 
  setNeedTranslucent(true, false); 
 } 
 /** 
  *         ,       
  * 
  * @param translucent 
  */ 
 public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) { 
  if (translucent) { 
   layRoot.setBackgroundDrawable(null); 
  } 
  if (!titleInitVisibile) { 
   tvTitle.setVisibility(View.GONE); 
  } 
 } 
 /** 
  *      
  * 
  * @param strTitle 
  */ 
 public void setTitle(String strTitle) { 
  if (!TextUtils.isEmpty(strTitle)) { 
   tvTitle.setText(strTitle); 
  } else { 
   tvTitle.setVisibility(View.GONE); 
  } 
 } 
 /** 
  *      
  * 
  * @param strTitle 
  * @param resIdLeft 
  * @param strLeft 
  * @param resIdRight 
  * @param strRight 
  * @param listener 
  */ 
 public void setData(String strTitle, int resIdLeft, String strLeft, int resIdRight, String strRight, final ActionBarClickListener listener) { 
  if (!TextUtils.isEmpty(strTitle)) { 
   tvTitle.setText(strTitle); 
  } else { 
   tvTitle.setVisibility(View.GONE); 
  } 
  if (!TextUtils.isEmpty(strLeft)) { 
   tvLeft.setText(strLeft); 
   tvLeft.setVisibility(View.VISIBLE); 
  } else { 
   tvLeft.setVisibility(View.GONE); 
  } 
  if (!TextUtils.isEmpty(strRight)) { 
   tvRight.setText(strRight); 
   tvRight.setVisibility(View.VISIBLE); 
  } else { 
   tvRight.setVisibility(View.GONE); 
  } 
  if (resIdLeft == 0) { 
   iconLeft.setVisibility(View.GONE); 
  } else { 
   iconLeft.setBackgroundResource(resIdLeft); 
   iconLeft.setVisibility(View.VISIBLE); 
  } 
  if (resIdRight == 0) { 
   iconRight.setVisibility(View.GONE); 
  } else { 
   iconRight.setBackgroundResource(resIdRight); 
   iconRight.setVisibility(View.VISIBLE); 
  } 
  if (listener != null) { 
   layLeft = findViewById(R.id.lay_actionbar_left); 
   layRight = findViewById(R.id.lay_actionbar_right); 
   layLeft.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     listener.onLeftClick(); 
    } 
   }); 
   layRight.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     listener.onRightClick(); 
    } 
   }); 
  } 
 } 
} 
다음은 actionbartrans.xml 코드

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:id="@+id/lay_transroot" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:background="@color/colorPrimary" 
 android:orientation="vertical"> 
 <View 
  android:id="@+id/v_statusbar" 
  android:layout_width="match_parent" 
  android:layout_height="1.0dp" /> 
 <RelativeLayout 
  android:layout_width="match_parent" 
  android:layout_height="45dp" 
  android:orientation="vertical"> 
  <RelativeLayout 
   android:id="@+id/lay_actionbar_left" 
   android:layout_width="100dp" 
   android:layout_height="match_parent" 
   android:orientation="horizontal"> 
   <ImageView 
    android:id="@+id/iv_actionbar_left" 
    android:layout_width="20dp" 
    android:layout_height="20dp" 
    android:layout_centerVertical="true" 
    android:layout_marginLeft="10dp" 
    android:background="@mipmap/ic_left_light" 
    android:visibility="gone" /> 
   <TextView 
    android:id="@+id/tv_actionbar_left" 
    style="@style/text_white" 
    android:layout_height="match_parent" 
    android:layout_marginLeft="10dp" 
    android:layout_toRightOf="@+id/iv_actionbar_left" 
    android:gravity="center_vertical" 
    android:maxLength="2" 
    android:singleLine="true" 
    android:text="  " 
    android:visibility="gone" /> 
  </RelativeLayout> 
  <TextView 
   android:id="@+id/tv_actionbar_title" 
   style="@style/text_white" 
   android:layout_centerInParent="true" 
   android:text="  " 
   android:textSize="16sp" /> 
  <RelativeLayout 
   android:id="@+id/lay_actionbar_right" 
   android:layout_width="100dp" 
   android:layout_height="match_parent" 
   android:layout_alignParentRight="true" 
   android:gravity="right" 
   android:orientation="horizontal"> 
   <View 
    android:id="@+id/v_actionbar_right" 
    android:layout_width="20dp" 
    android:layout_height="20dp" 
    android:layout_alignParentRight="true" 
    android:layout_centerVertical="true" 
    android:layout_marginRight="10dp" 
    android:visibility="gone" /> 
   <TextView 
    android:id="@+id/tv_actionbar_right" 
    style="@style/text_white" 
    android:layout_height="match_parent" 
    android:layout_marginRight="10dp" 
    android:layout_toLeftOf="@+id/v_actionbar_right" 
    android:gravity="center_vertical|right" 
    android:singleLine="true" 
    android:visibility="gone" /> 
  </RelativeLayout> 
 </RelativeLayout> 
</LinearLayout> 
여기 서 저 는 안 드 로 이 드:fitsSystem Windows="true"속성 을 사용 하지 않 았 고 StatusBarUtils 도 사용 하지 않 았 습 니 다.사용 할 때 호 환 문제 가 발생 하기 쉽다 는 것 을 알 았 기 때 문 입 니 다.
그래서 제 방법 은 0.0dp 높이 의 status bar 를 설명 한 다음 에 상태 표시 줄 높이 를 가 져 와 서 호 환 을 실현 하 는 것 입 니 다.사실은 이렇게 하 는 호환성 이 가장 좋다 는 것 을 증명 한다.
상태 표시 줄 높이 코드 가 져 오기:

/** 
 *         
 * 
 * @return 
 */ 
public int getStatusBarHeight() { 
 //  status_bar_height   ID 
 int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); 
 if (resourceId > 0) { 
  //    ID         
  return getResources().getDimensionPixelSize(resourceId); 
 } 
 return 0; 
} 
status bar 높이 설정:

/** 
 *         
 * 
 * @param statusBarHeight 
 */ 
public void setStatusBarHeight(int statusBarHeight) { 
 ViewGroup.LayoutParams params = vStatusBar.getLayoutParams(); 
 params.height = statusBarHeight; 
 vStatusBar.setLayoutParams(params); 
} 
오픈 그 라 데 이 션:

/** 
 *          
 */ 
 public void setNeedTranslucent() { 
  setNeedTranslucent(true, false); 
 } 
 /** 
 *         ,       
 * 
 * @param translucent 
 */ 
 public void setNeedTranslucent(boolean translucent, boolean titleInitVisibile) { 
  if (translucent) { 
   layRoot.setBackgroundDrawable(null); 
  } 
  if (!titleInitVisibile) { 
   tvTitle.setVisibility(View.GONE); 
  } 
 } 
STEP 3:ScrollView 상단 신축 실현
여기까지 왔 으 니 반드시 말씀 드 려 야 합 니 다.개인 프로젝트 에 사용 되 기 때문에 기능 을 강하 게 만 들 지 않 았 습 니 다.저 는 모두 가장 간단 하고 효과 적 인 방식 으로 이 루어 졌 습 니 다.따라서 코드 는 gitHub 에서 여러 번 다운로드 되 는 오픈 소스 프로젝트 처럼 확장 성 이 높 지 않 습 니 다.
시간 관계,내 가 직접 코드 를 붙 일 게.코드 에 주석 을 다 썼어.

package test.com.widget; 
 import android.animation.ObjectAnimator; 
import android.animation.ValueAnimator; 
import android.content.Context; 
import android.graphics.Color; 
import android.support.annotation.ColorInt; 
import android.support.v4.graphics.ColorUtils; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.WindowManager; 
import android.widget.ScrollView; 
import test.com.R; 
import test.com.utils.SizeUtils; 
/** 
 * Created by   (Milo) on 2017/2/13. 
 * email:[email protected] 
 */ 
public class TranslucentScrollView extends ScrollView { 
 static final String TAG = "TranslucentScrollView"; 
 //     
 private View zoomView; 
 //         
 private int zoomViewInitHeight = 0; 
 //          
 private float mFirstPosition = 0; 
 //        
 private Boolean mScaling = false; 
 //      
 private View transView; 
 //     
 private int transColor = Color.WHITE; 
 //       
 private int transStartY = 50; 
 //       
 private int transEndY = 300; 
 //        ,Y ,50dp 
 private final int DFT_TRANSSTARTY = 50; 
 //        ,Y ,300dp 
 private final int DFT_TRANSENDY = 300; 
 private TranslucentScrollView.TranslucentChangedListener translucentChangedListener; 
 public interface TranslucentChangedListener { 
  /** 
   *      ,    0-255 
   * 
   * @param transAlpha 
   */ 
  void onTranslucentChanged(int transAlpha); 
 } 
 public TranslucentScrollView(Context context) { 
  super(context); 
 } 
 public TranslucentScrollView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 public TranslucentScrollView(Context context, AttributeSet attrs, int defStyleAttr) { 
  super(context, attrs, defStyleAttr); 
 } 
 public void setTranslucentChangedListener(TranslucentScrollView.TranslucentChangedListener translucentChangedListener) { 
  this.translucentChangedListener = translucentChangedListener; 
 } 
 /** 
  *        
  * 
  * @param zoomView 
  */ 
 public void setPullZoomView(View zoomView) { 
  this.zoomView = zoomView; 
  zoomViewInitHeight = zoomView.getLayoutParams().height; 
  if (zoomViewInitHeight == LayoutParams.MATCH_PARENT || zoomViewInitHeight == WindowManager.LayoutParams.WRAP_CONTENT) { 
   zoomView.post(new Runnable() { 
    @Override 
    public void run() { 
     zoomViewInitHeight = TranslucentScrollView.this.zoomView.getHeight(); 
    } 
   }); 
  } 
 } 
 /** 
  *        
  * 
  * @param transView       
  */ 
 public void setTransView(View transView) { 
  setTransView(transView, getResources().getColor(R.color.colorPrimary), SizeUtils.dip2px(getContext(), DFT_TRANSSTARTY), SizeUtils.dip2px(getContext(), DFT_TRANSENDY)); 
 } 
 /** 
  *        
  * 
  * @param transView       
  * @param transColor      
  * @param transEndY        
  */ 
 public void setTransView(View transView, @ColorInt int transColor, int transStartY, int transEndY) { 
  this.transView = transView; 
  //    -   
  this.transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, 0)); 
  this.transStartY = transStartY; 
  this.transEndY = transEndY; 
  this.transColor = transColor; 
  if (transStartY > transEndY) { 
   throw new IllegalArgumentException("transStartY      transEndY .. "); 
  } 
 } 
 /** 
  *       
  * 
  * @return 
  */ 
 private int getTransAlpha() { 
  float scrollY = getScrollY(); 
  if (transStartY != 0) { 
   if (scrollY <= transStartY) { 
    return 0; 
   } else if (scrollY >= transEndY) { 
    return 255; 
   } else { 
    return (int) ((scrollY - transStartY) / (transEndY - transStartY) * 255); 
   } 
  } else { 
   if (scrollY >= transEndY) { 
    return 255; 
   } 
   return (int) ((transEndY - scrollY) / transEndY * 255); 
  } 
 } 
 /** 
  *   ZoomView 
  */ 
 private void resetZoomView() { 
  final ViewGroup.LayoutParams lp = zoomView.getLayoutParams(); 
  final float h = zoomView.getLayoutParams().height;// ZoomView     
  //      
  ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration(200); 
  anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
   @Override 
   public void onAnimationUpdate(ValueAnimator animation) { 
    float cVal = (Float) animation.getAnimatedValue(); 
    lp.height = (int) (h - (h - zoomViewInitHeight) * cVal); 
    zoomView.setLayoutParams(lp); 
   } 
  }); 
  anim.start(); 
 } 
 @Override 
 protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
  super.onScrollChanged(l, t, oldl, oldt); 
  int transAlpha = getTransAlpha(); 
  if (transView != null) { 
   Log.d(TAG, "[onScrollChanged .. in ],     == " + transAlpha); 
   transView.setBackgroundColor(ColorUtils.setAlphaComponent(transColor, transAlpha)); 
  } 
  if (translucentChangedListener != null) { 
   translucentChangedListener.onTranslucentChanged(transAlpha); 
  } 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  if (zoomView != null) { 
   ViewGroup.LayoutParams params = zoomView.getLayoutParams(); 
   switch (event.getAction()) { 
    case MotionEvent.ACTION_UP: 
     //          
     mScaling = false; 
     resetZoomView(); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     if (!mScaling) { 
      if (getScrollY() == 0) { 
       mFirstPosition = event.getY(); 
      } else { 
       break; 
      } 
     } 
     int distance = (int) ((event.getY() - mFirstPosition) * 0.6); 
     if (distance < 0) { 
      break; 
     } 
     mScaling = true; 
     params.height = zoomViewInitHeight + distance; 
     Log.d(TAG, "params.height == " + params.height + ", zoomViewInitHeight == " + zoomViewInitHeight + ", distance == " + distance); 
     zoomView.setLayoutParams(params); 
     return true; 
   } 
  } 
  return super.onTouchEvent(event); 
 } 
} 
총결산
위 에서 말 한 것 은 소 편 이 소개 한 안 드 로 이 드 몰입 식 상태 표시 줄+actionBar 그 라 데 이 션+scrollView 상단 신축 입 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기