Android4.4以上推出了Toolbar,改變程序的style屬性就可以給手機的標題欄填充顏色洼冻,可以是你設置好的系統(tǒng)的主題色蓝厌,也可以是自己填充的顏色诞帐,其實這個效果在iOS早就有了,但在Android中還是很少見的祸穷。在iOS中性穿,最常見的Navigationbar的效果就是一個轉場動畫(多出現于兩個界面切換的時候),一個就是隨著手勢滑動背景漸變(多出現于詳情頁)雷滚。今天我們就來實現下大多出現于詳情頁的這個漸變效果的標題欄需曾。
具體效果見:點擊打開鏈接
接下來我們就來實現這個效果。
首先祈远,我們要先把手機上面的狀態(tài)欄的顏色背景隱藏掉呆万,在這里會有一個坑,在小米和魅族手機里车份,好想說是MIUI6以上谋减,上面狀態(tài)欄上的時間啊什么的文字默認的顏色是白色,如果你的Toolbar的背景是相對深顏色的話扫沼,是沒有問題的出爹,但是如果你的Toolbar是相對淺的背景顏色庄吼,那么很可能這些時間文字會顯示不出來,那么就要修改上面狀態(tài)欄的顏色了严就。具體可以參考這篇:點擊打開鏈接
先在style里設置总寻,這是我的style.xml:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="android:windowBackground">@color/devide</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:textColorSecondary">@color/white</item>
<item name="android:textColorPrimary">@color/white</item>
<item name="toolbarStyle">@style/ToolbarStyle</item>-
<item name="colorControlNormal">@android:color/white</item>
</style>
<style name="ToolbarStyle" parent="Widget.AppCompat.Toolbar">
<item name="contentInsetStart">0dp</item>
<item name="colorControlNormal">@android:color/white</item>
</style>
</resources>
接下來我們就要把狀態(tài)欄設置為透明:
private void setTranslucentWindows(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明狀態(tài)欄
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
以下是我寫的標題欄的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="@+id/layout_toolbar_my_container"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/base"
android:paddingBottom="0dp">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="44dp"
android:elevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/layout_toolbar_details_back"
android:layout_width="60dp"
android:onClick="onBack"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:src="@mipmap/btn_back" />
</RelativeLayout>
<TextView
android:visibility="gone"
android:id="@+id/text_toolbar_index"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是一個標題"
android:textColor="@color/white"
android:textSize="17dp" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
</RelativeLayout>
</RelativeLayout>
將標題欄的布局文件引入到我們界面的布局文件里,我們是相當于在recyclerView的header上疊加了一層透明的標題欄梢为,這里對recyclerView的adapter的所有操作我都集成了一個通用格式來進行操作渐行,方便很多。我給recyclerView添加了一個header抖誉,在這里為了簡便殊轴,用imageView來代替了輪播圖衰倦。為了達到漸變的效果袒炉,我們要去監(jiān)聽滑動事件,是否滑動到imageView的高度樊零,也就是把imageView隱藏我磁,當正好隱藏的時候標題欄的文字將出現(這個一般看交互,如果大圖下面有標題驻襟,一般建議標題覆蓋以后夺艰,標題欄上的標題再顯示),當前的y與整體要滑動距離的百分比來控制標題欄的背景透明度沉衣。在這里要注意郁副,當onCreate方法的時候,一個view的getMeasuredHeight()方法或者寬度的方法獲得的都是0豌习,因為這個時候你的view還沒有draw上去存谎,只有當onCreate方法執(zhí)行完了以后,控件才會被onMeasure肥隆。所以有兩種策略既荚,一種是我以下代碼實現的,等view的onMeasure好了以后再去調用方法栋艳,還有一種是去注冊一個ViewTreeObserver的監(jiān)聽回調恰聘,具體大家可以去自行百度。ok吸占,下面貼上Activity里的代碼:
public class MainActivity extends AppCompatActivity {
@Bind(R.id.recycler)
RecyclerView recyclerView;
@Bind(R.id.layout_toolbar_my_container)
RelativeLayout layoutToolBarBackground;
@Bind(R.id.text_toolbar_index)
TextView centerText;
private ArrayList<Model> modelList = new ArrayList<>();
private MyRecyclerAdapter adapter;
private LinearLayoutManager layoutManager;
private int itemIndex;
private ToolBarBackgroundController toolBarBackgroundController;
private int anchorHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTranslucentWindows(this);
ButterKnife.bind(this);
layoutManager = new LinearLayoutManager(this.getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST,
R.drawable.devide_line_gray, 0));
initHead();
initData();
initView();
}
private void initHead() {
layoutToolBarBackground.setBackgroundColor(Color.TRANSPARENT);
toolBarBackgroundController = new ToolBarBackgroundController(layoutToolBarBackground);
}
public class ToolBarBackgroundController {
private View layoutToolbar;
public ToolBarBackgroundController(View layoutToolbar) {
this.layoutToolbar = layoutToolbar;
layoutToolbar.setBackgroundColor(Color.TRANSPARENT);
}
public void setTransparent(boolean needTransparent) {
if (needTransparent) {
//變透明
centerText.setVisibility(View.GONE);
} else {
layoutToolbar.setBackgroundColor(getResources().getColor(R.color.base));
centerText.setVisibility(View.VISIBLE);
}
}
}
private void setTranslucentWindows(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明狀態(tài)欄
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
private int getStatusBarHeight(Context context) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
return context.getResources().getDimensionPixelSize(resourceId);
} else return 0;
}
private void initData() {
for (int i = 0; i < 20; i++) {
Model model = new Model();
model.setName("jjq" + i);
model.setDesc("哈哈哈哈哈哈哈哈");
modelList.add(model);
}
}
private void initView() {
if (adapter == null) {
adapter = new MyRecyclerAdapter();
} else {
adapter.notifyDataSetChanged();
}
adapter.initData(false);
adapter.appendData(modelList);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new OnScrollColorChangeListener());
}
private class OnScrollColorChangeListener extends RecyclerView.OnScrollListener {
private boolean isTrans = true;
private int y = 0;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (anchorHeight != 0) {
y += dy;
boolean needTrans = y <= anchorHeight;
if (needTrans != isTrans) {
isTrans = needTrans;
toolBarBackgroundController.setTransparent(needTrans);
} else {
if (y / anchorHeight < 1) {
layoutToolBarBackground.setBackgroundColor(getResources().getColor(R.color.base));
layoutToolBarBackground.getBackground().setAlpha((int) ((float) y / anchorHeight * 255));
}
}
}
}
}
private class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int TYPE_HEADER = 0x1000;
private final int TYPE_NORMAL = 0x2000;
private final int TYPE_FOOTER = 0x3000;
private final int TYPE_EMPTY = 0x4000;
private final int TYPE_THEME = 0x5000;
private ArrayList<MyItemInfo> itemInfos;
private boolean needFooter = false;
private boolean hasFooter = false;
public class MyItemInfo {
int type;
Model model;
public MyItemInfo(int type, Model model) {
this.type = type;
this.model = model;
}
}
public MyRecyclerAdapter() {
itemInfos = new ArrayList<>();
}
public void initData(boolean needFooter) {
this.needFooter = needFooter;
this.hasFooter = false;
int oldCount = itemInfos.size();
itemInfos.clear();
this.notifyItemRangeRemoved(0, oldCount);
itemInfos.add(new MyItemInfo(TYPE_HEADER, null));
//itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
//this.notifyItemRangeInserted(0, 2);
}
public void appendData(ArrayList<Model> models) {
int oldCount = itemInfos.size();
if (hasFooter) {
itemInfos.remove(oldCount - 1);
this.notifyItemRemoved(oldCount - 1);
oldCount--;
}
int size = models.size();
for (int i = 0; i < size; i++) {
itemInfos.add(new MyItemInfo(TYPE_NORMAL, models.get(i)));
}
this.notifyItemRangeInserted(oldCount + 1, size);
if (needFooter) {
itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
this.notifyItemInserted(itemInfos.size() - 1);
hasFooter = true;
}
}
public void removeFooter() {
int oldCount = itemInfos.size();
itemInfos.remove(oldCount - 1);
notifyItemRemoved(oldCount - 1);
}
public void appendEmptyView() {
int oldCount = itemInfos.size();
if (hasFooter) {
itemInfos.remove(oldCount - 1);
this.notifyItemRemoved(oldCount - 1);
oldCount--;
}
itemInfos.add(new MyItemInfo(TYPE_EMPTY, null));
notifyItemRangeInserted(oldCount, 1);
}
@Override
public int getItemViewType(int position) {
return itemInfos.get(position).type;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = null;
switch (viewType) {
case TYPE_HEADER:
view = inflater.inflate(R.layout.layout_main_recycler_head, parent, false);
return new MyHeaderItemHolder(view, MainActivity.this);
case TYPE_NORMAL:
view = inflater.inflate(R.layout.layout_list_item, parent, false);
return new NormalViewHolder(view);
case TYPE_EMPTY:
return null;
case TYPE_FOOTER:
return null;
default:
return null;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
switch (viewHolder.getItemViewType()) {
case TYPE_NORMAL:
NormalViewHolder normalViewHolder = (NormalViewHolder) viewHolder;
normalViewHolder.setContent(itemInfos.get(i).model, i);
break;
case TYPE_HEADER:
MyHeaderItemHolder headerViewHolder = (MyHeaderItemHolder) viewHolder;
headerViewHolder.setContent();
break;
case TYPE_FOOTER:
case TYPE_EMPTY:
break;
default:
break;
}
}
@Override
public int getItemCount() {
return itemInfos.size();
}
private class EmptyItemHolder extends RecyclerView.ViewHolder {
public EmptyItemHolder(View itemView) {
super(itemView);
}
}
private class MyHeaderItemHolder extends RecyclerView.ViewHolder {
private Context context;
private ImageView imageView;
public MyHeaderItemHolder(View itemView, Context context) {
super(itemView);
this.context = context;
imageView = (ImageView) itemView.findViewById(R.id.img_main_recycler_head_banner);
imageView.post(new Runnable() {
@Override
public void run() {
anchorHeight = imageView.getMeasuredHeight() - layoutToolBarBackground.getMeasuredHeight();
}
});
}
//填充頭部內容
public void setContent() {
}
}
private class NormalViewHolder extends RecyclerView.ViewHolder {
private Model model;
private TextView nameView;
private TextView descView;
public NormalViewHolder(View itemView) {
super(itemView);
nameView = (TextView) itemView.findViewById(R.id.text_list_item_name);
descView = (TextView) itemView.findViewById(R.id.text_list_item_desc);
itemView.setOnClickListener(new OnItemClickListener());
}
public void setContent(Model model, int index) {
this.model = model;
nameView.setText(model.getName());
descView.setText(model.getDesc());
itemIndex = index;
}
private class OnItemClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
}
}
}
private class FooterViewHolder extends RecyclerView.ViewHolder {
public FooterViewHolder(View itemView) {
super(itemView);
}
}
}
}
ok晴叨,到這里demo就搞定了!當然如果你的標題欄上的文字太長的話矾屯,你也可以自己給textView加上跑馬燈效果篙螟,很簡單,不知道的人可以自行去谷歌百度问拘,記得給textView加上焦點就可以了遍略。項目地址:點擊打開鏈接