package com.example.jingbin.cloudreader.base;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.transition.ArcMotion;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.example.jingbin.cloudreader.R;
import com.example.jingbin.cloudreader.databinding.BaseHeaderTitleBarBinding;
import com.example.jingbin.cloudreader.utils.CommonUtils;
import com.example.jingbin.cloudreader.utils.PerfectClickListener;
import com.example.jingbin.cloudreader.view.CustomChangeBounds;
import com.example.jingbin.cloudreader.view.MyNestedScrollView;
import com.example.jingbin.cloudreader.view.statusbar.StatusBarUtil;
import com.example.jingbin.cloudreader.view.test.StatusBarUtils;
import java.lang.reflect.Method;
import jp.wasabeef.glide.transformations.BlurTransformation;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;
/**
* Created by jingbin on 16/12/12.
* 电影
* 书籍
* 音乐等详情页
* 根布局:fitsSystemWindows 惹的祸
*/
public abstract class BaseHeaderActivity<HV extends ViewDataBinding, SV extends ViewDataBinding> extends AppCompatActivity {
// 标题
protected BaseHeaderTitleBarBinding bindingTitleView;
// 内容布局头部
protected HV bindingHeaderView;
// 内容布局view
protected SV bindingContentView;
private LinearLayout llProgressBar;
private View refresh;
// 滑动多少距离后标题不透明
private int slidingDistance;
// 这个是高斯图背景的高度
private int imageBgHeight;
private AnimationDrawable mAnimationDrawable;
private CompositeSubscription mCompositeSubscription;
protected <T extends View> T getView(int id) {
return (T) findViewById(id);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void setContentView(@LayoutRes int layoutResID) {
View ll = getLayoutInflater().inflate(R.layout.activity_header_base, null);
// 内容
bindingContentView = DataBindingUtil.inflate(getLayoutInflater(), layoutResID, null, false);
// 头部
bindingHeaderView = DataBindingUtil.inflate(getLayoutInflater(), setHeaderLayout(), null, false);
// 标题
bindingTitleView = DataBindingUtil.inflate(getLayoutInflater(), R.layout.base_header_title_bar, null, false);
// title (如自定义很强可以拿出去)
RelativeLayout.LayoutParams titleParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bindingTitleView.getRoot().setLayoutParams(titleParams);
RelativeLayout mTitleContainer = (RelativeLayout) ll.findViewById(R.id.title_container);
mTitleContainer.addView(bindingTitleView.getRoot());
getWindow().setContentView(ll);
// header
RelativeLayout.LayoutParams headerParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bindingHeaderView.getRoot().setLayoutParams(headerParams);
RelativeLayout mHeaderContainer = (RelativeLayout) ll.findViewById(R.id.header_container);
mHeaderContainer.addView(bindingHeaderView.getRoot());
getWindow().setContentView(ll);
// content
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
bindingContentView.getRoot().setLayoutParams(params);
RelativeLayout mContainer = (RelativeLayout) ll.findViewById(R.id.container);
mContainer.addView(bindingContentView.getRoot());
getWindow().setContentView(ll);
llProgressBar = getView(R.id.ll_progress_bar);
refresh = getView(R.id.ll_error_refresh);
// 设置自定义元素共享切换动画
setMotion(setHeaderPicView(),false);
// 初始化滑动渐变
initSlideShapeTheme(setHeaderImgUrl(), setHeaderImageView());
// 设置toolbar
setToolBar();
ImageView img = getView(R.id.img_progress);
// 加载动画
mAnimationDrawable = (AnimationDrawable) img.getDrawable();
// 默认进入页面就开启动画
if (!mAnimationDrawable.isRunning()) {
mAnimationDrawable.start();
}
// 点击加载失败布局
refresh.setOnClickListener(new PerfectClickListener() {
@Override
protected void onNoDoubleClick(View v) {
showLoading();
onRefresh();
}
});
bindingContentView.getRoot().setVisibility(View.GONE);
}
/**
* a. 布局高斯透明图 header布局
*/
protected abstract int setHeaderLayout();
/**
* b. 设置头部header高斯背景 imgUrl
*/
protected abstract String setHeaderImgUrl();
/**
* c. 设置头部header布局 高斯背景ImageView控件
*/
protected abstract ImageView setHeaderImageView();
/**
* 设置头部header布局 左侧的图片(需要设置曲线路径切换动画时重写)
*/
protected ImageView setHeaderPicView() {
return new ImageView(this);
}
/**
* 1. 标题
*/
public void setTitle(CharSequence text) {
bindingTitleView.tbBaseTitle.setTitle(text);
}
/**
* 2. 副标题
*/
protected void setSubTitle(CharSequence text) {
bindingTitleView.tbBaseTitle.setSubtitle(text);
}
/**
* 3. toolbar 单击"更多信息"
*/
protected void setTitleClickMore() {
}
/**
* 设置自定义 Shared Element切换动画
* 默认不开启曲线路径切换动画,
* 开启需要重写setHeaderPicView(),和调用此方法并将isShow值设为true
*
* @param imageView 共享的图片
* @param isShow 是否显示曲线动画
*/
protected void setMotion(ImageView imageView, boolean isShow) {
if (!isShow) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//定义ArcMotion
ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);
//插值器,控制速度
Interpolator interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.fast_out_slow_in);
//实例化自定义的ChangeBounds
CustomChangeBounds changeBounds = new CustomChangeBounds();
changeBounds.setPathMotion(arcMotion);
changeBounds.setInterpolator(interpolator);
changeBounds.addTarget(imageView);
//将切换动画应用到当前的Activity的进入和返回
getWindow().setSharedElementEnterTransition(changeBounds);
getWindow().setSharedElementReturnTransition(changeBounds);
}
}
/**
* 设置toolbar
*/
protected void setToolBar() {
setSupportActionBar(bindingTitleView.tbBaseTitle);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//去除默认Title显示
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.icon_back);
}
// 手动设置才有效果
bindingTitleView.tbBaseTitle.setTitleTextAppearance(this, R.style.ToolBar_Title);
bindingTitleView.tbBaseTitle.setSubtitleTextAppearance(this, R.style.Toolbar_SubTitle);
bindingTitleView.tbBaseTitle.inflateMenu(R.menu.base_header_menu);
bindingTitleView.tbBaseTitle.setOverflowIcon(ContextCompat.getDrawable(this, R.drawable.actionbar_more));
bindingTitleView.tbBaseTitle.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
bindingTitleView.tbBaseTitle.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionbar_more:// 更多信息
setTitleClickMore();
break;
}
return false;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.base_header_menu, menu);
return true;
}
/**
* 显示popu内的图片
*/
@Override
protected boolean onPrepareOptionsPanel(View view, Menu menu) {
if (menu != null) {
if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
try {
Method m = menu.getClass().getDeclaredMethod(
"setOptionalIconsVisible", Boolean.TYPE);
m.setAccessible(true);
m.invoke(menu, true);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "onMenuOpened...unable to set icons for overflow menu", e);
}
}
}
return super.onPrepareOptionsPanel(view, menu);
}
/**
* *** 初始化滑动渐变 一定要实现 ******
*
* @param imgUrl header头部的高斯背景imageUrl
* @param mHeaderBg header头部高斯背景ImageView控件
*/
protected void initSlideShapeTheme(String imgUrl, ImageView mHeaderBg) {
setImgHeaderBg(imgUrl);
// toolbar 的高
int toolbarHeight = bindingTitleView.tbBaseTitle.getLayoutParams().height;
final int headerBgHeight = toolbarHeight + StatusBarUtil.getStatusBarHeight(this);
// 使背景图向上移动到图片的最低端,保留(titlebar+statusbar)的高度
ViewGroup.LayoutParams params = bindingTitleView.ivBaseTitlebarBg.getLayoutParams();
ViewGroup.MarginLayoutParams ivTitleHeadBgParams = (ViewGroup.MarginLayoutParams) bindingTitleView.ivBaseTitlebarBg.getLayoutParams();
int marginTop = params.height - headerBgHeight;
ivTitleHeadBgParams.setMargins(0, -marginTop, 0, 0);
bindingTitleView.ivBaseTitlebarBg.setImageAlpha(0);
StatusBarUtils.setTranslucentImageHeader(this, 0, bindingTitleView.tbBaseTitle);
// 上移背景图片,使空白状态栏消失(这样下方就空了状态栏的高度)
if (mHeaderBg != null) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mHeaderBg.getLayoutParams();
layoutParams.setMargins(0, -StatusBarUtil.getStatusBarHeight(this), 0, 0);
ViewGroup.LayoutParams imgItemBgparams = mHeaderBg.getLayoutParams();
// 获得高斯图背景的高度
imageBgHeight = imgItemBgparams.height;
}
// 变色
initScrollViewListener();
initNewSlidingParams();
}
/**
* 加载titlebar背景
*/
private void setImgHeaderBg(String imgUrl) {
if (!TextUtils.isEmpty(imgUrl)) {
// 高斯模糊背景 原来 参数:12,5 23,4
Glide.with(this).load(imgUrl)
.error(R.drawable.stackblur_default)
.bitmapTransform(new BlurTransformation(this, 23, 4)).listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
bindingTitleView.tbBaseTitle.setBackgroundColor(Color.TRANSPARENT);
bindingTitleView.ivBaseTitlebarBg.setImageAlpha(0);
bindingTitleView.ivBaseTitlebarBg.setVisibility(View.VISIBLE);
return false;
}
}).into(bindingTitleView.ivBaseTitlebarBg);
}
}
private void initScrollViewListener() {
// 为了兼容23以下
((MyNestedScrollView) findViewById(R.id.mns_base)).setOnScrollChangeListener(new MyNestedScrollView.ScrollInterface() {
@Override
public void onScrollChange(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
scrollChangeHeader(scrollY);
}
});
}
private void initNewSlidingParams() {
int titleBarAndStatusHeight = (int) (CommonUtils.getDimens(R.dimen.nav_bar_height) + StatusBarUtil.getStatusBarHeight(this));
// 减掉后,没到顶部就不透明了
slidingDistance = imageBgHeight - titleBarAndStatusHeight - (int) (CommonUtils.getDimens(R.dimen.base_header_activity_slide_more));
}
/**
* 根据页面滑动距离改变Header方法
*/
private void scrollChangeHeader(int scrolledY) {
if (scrolledY < 0) {
scrolledY = 0;
}
float alpha = Math.abs(scrolledY) * 1.0f / (slidingDistance);
Drawable drawable = bindingTitleView.ivBaseTitlebarBg.getDrawable();
if (drawable == null) {
return;
}
if (scrolledY <= slidingDistance) {
// title部分的渐变
drawable.mutate().setAlpha((int) (alpha * 255));
bindingTitleView.ivBaseTitlebarBg.setImageDrawable(drawable);
} else {
drawable.mutate().setAlpha(255);
bindingTitleView.ivBaseTitlebarBg.setImageDrawable(drawable);
}
}
protected void showLoading() {
if (llProgressBar.getVisibility() != View.VISIBLE) {
llProgressBar.setVisibility(View.VISIBLE);
}
// 开始动画
if (!mAnimationDrawable.isRunning()) {
mAnimationDrawable.start();
}
if (bindingContentView.getRoot().getVisibility() != View.GONE) {
bindingContentView.getRoot().setVisibility(View.GONE);
}
if (refresh.getVisibility() != View.GONE) {
refresh.setVisibility(View.GONE);
}
}
protected void showContentView() {
if (llProgressBar.getVisibility() != View.GONE) {
llProgressBar.setVisibility(View.GONE);
}
// 停止动画
if (mAnimationDrawable.isRunning()) {
mAnimationDrawable.stop();
}
if (refresh.getVisibility() != View.GONE) {
refresh.setVisibility(View.GONE);
}
if (bindingContentView.getRoot().getVisibility() != View.VISIBLE) {
bindingContentView.getRoot().setVisibility(View.VISIBLE);
}
}
protected void showError() {
if (llProgressBar.getVisibility() != View.GONE) {
llProgressBar.setVisibility(View.GONE);
}
// 停止动画
if (mAnimationDrawable.isRunning()) {
mAnimationDrawable.stop();
}
if (refresh.getVisibility() != View.VISIBLE) {
refresh.setVisibility(View.VISIBLE);
}
if (bindingContentView.getRoot().getVisibility() != View.GONE) {
bindingContentView.getRoot().setVisibility(View.GONE);
}
}
/**
* 失败后点击刷新
*/
protected void onRefresh() {
}
public void addSubscription(Subscription s) {
if (this.mCompositeSubscription == null) {
this.mCompositeSubscription = new CompositeSubscription();
}
this.mCompositeSubscription.add(s);
}
@Override
public void onDestroy() {
super.onDestroy();
if (this.mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
this.mCompositeSubscription.unsubscribe();
}
}
public void removeSubscription() {
if (this.mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
this.mCompositeSubscription.unsubscribe();
}
}
}