26
2017
09

Android开发--折叠式标题

要实现可折叠式的标题栏可以借助CollapsingToolbarLayout来实现。CollapsingToolbarLayout是不能单独存在的,只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoordinatorLayout的子布局。

在正文部分,也就是点击进入到文章正文。我们这里做成折叠式的模式,搜先我们需要定义正文的头部和正文的内容

头部如下操作

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="website.dengta.drawerlayout.FruitActivity">

    <android.support.design.widget.AppBarLayout
    android:id="@+id/appBar"
    android:layout_width="match_parent"
    android:layout_height="250dp">

        <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"


            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent" 
                android:id="@+id/fruit_image_view"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                />

             <android.support.v7.widget.Toolbar
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin">

                </android.support.v7.widget.Toolbar>

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>

app:contentScrim 属性用于指定CollapsingToolbarLayout 在趋于折叠状态以及折叠之后的背泉色,其实CollapsingToolbarLayout在折叠之后就是一个普通的Toolbar, 那么背景色肯定应该是colorPrimary 了,具体的效果我们待会儿就能看到。app:layout— scrol lFlags 属性我们也是见过的,只不过之前是给Toolbar 指定的,现在也移到外面来了。其中, scroll 表示CollapsingToolbarLayout 会随着水果内容详情的滚动一起滚动, exitUntilCol lapsed 表示当CollapsingToolbarLayout 随着滚动完成折叠之后就保留在界面上,不再移出屏幕。

效果如图所示

这里定义的大多数属性我们都是见过的,就不再解释了,只有一个app:layout_collapseMode 比较陌生。它用于指定当前控件在CollapsingToolbarLayout 折叠过程中的折叠模式,其中Toolbar 指定成pin, 表示在折叠的过程中位置始终保持不变, ImageView 指定成parallax, 表示会在折叠的过程中产生一定的错位偏移,这种模式的视觉效果会非常好。


内容部分操作如下

继续操作上面的xml布局文件

 <!--正文内容部分-->
<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.CardView
            android:layout_marginBottom="15dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:layout_marginTop="35dp"
            app:cardCornerRadius="4dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/fruit_content_text"
                android:layout_margin="10dp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

        </android.support.v7.widget.CardView>

    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

NestedScrollView 在此基础之上还增加了嵌套响应滚动事件的功能。由于CoordinatorLayout 本身已经可以响应滚动事件了,因此我们在它的内部就需要使用NestedScrollView 或RecyclerView这样的布局。另外,这里还通过app:layout—behavior 属性指定了一个布局行为,这和之前在Recycler View 中的用法是一模一样的。


在文章正文中加入一个悬浮的评论按钮

<!--悬浮的评论按钮-->
<android.support.design.widget.FloatingActionButton
   android:layout_margin="16dp"
    android:src="@drawable/comments"
    app:layout_anchor="@id/appBar"
    app:layout_anchorGravity="bottom|end"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

FloatingActionButton 中使用app:layout_anchor 属性指定了一个描点,我们将描点
设置为AppBarLayout, 这样悬浮按钮就会出现在水果标题栏的区域内,接着又使用app:layout_anchorGravity 属性将悬浮按钮定位在标题栏区域的右下角。

效果如图所示


代码如下
FruitActivity.java

package website.dengta.drawerlayout;

import android.content.Intent;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;

public class FruitActivity extends AppCompatActivity {

public static final String FRUIT_NAME = "fruit_name";

public static final String FRUIT_IMAGE_ID = "fruit_image_id";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit);

Intent intent = getIntent();
String fruitName = intent.getStringExtra(FRUIT_NAME);
int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID,0);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
ImageView fruitImageView = (ImageView) findViewById(R.id.fruit_image_view);
TextView fruitContentText = (TextView) findViewById(R.id.fruit_content_text);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
collapsingToolbar.setTitle(fruitName);
Glide.with(this).load(fruitImageId).into(fruitImageView);


String fruitContent = generateFruitContent(fruitName);
fruitContentText.setText(fruitContent);
}

private String generateFruitContent(String fruitName) {
StringBuilder fruitContent = new StringBuilder();
for (int i = 0; i < 500; i++) {
fruitContent.append(fruitName);
}
return fruitContent.toString();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
        finish();
        return true;
        }
    return super.onOptionsItemSelected(item);
}
}

通过Intent 获取到传入的水果名和水果图片的资源id, 然后通过findViewByid() 方法拿到刚才在布局文件中定义的各个控件的实例。接着就是使用了Toolbar 的标准用法,将它作为ActionBar 显示,并启用HomeAsUp 按钮。由于HomeAsUp 按钮的默认图标就是一个返回箭头,这正是我们所期望的,因此就不用再额外设置别的图标了。

调用CollapsingToolbarLayout 的setTitle() 方法将水果名设置成当前界面的标题,然后使用Glide 加载传入的水果图片,并设置到标题栏的ImageView 上面。接着需要填充水果的内容详情,由于这只是一个示例程序,并不需要什么真实的数据,所以我使用了一个enerateFruitContent ()方法将水果名循环拼接500 次,从而生成了一个比较长的字符串,将它设置到了TextView 上面。

在onOptionsitemSelected() 方法中处理了HomeAsUp 按钮的点击事件,当点击了这个按钮时,就调用finish ()方法关闭当前的活动,从而返回上一个活动。


处理Recycler View的点击事件,让其可以进入到FruitActivity的布局中

 @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (mContext==null){
        mContext = parent.getContext();
    }

    View view = LayoutInflater.from(mContext).inflate(R.layout.fruit_item,parent,false);

    //处理点击事件
    final ViewHolder holder = new ViewHolder(view);
    holder.cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int position = holder.getAdapterPosition();
            Fruit fruit = mFruitList.get(position);
            Intent intent = new Intent(mContext,FruitActivity.class);
            intent.putExtra(FruitActivity.FRUIT_NAME,fruit.getName());
            intent.putExtra(FruitActivity.FRUIT_IMAGE_ID,fruit.getImageId());
            mContext.startActivity(intent);
        }
    });
    return new ViewHolder(view);
}

充分利用系统状态栏空间

想要让背景图能够和系统状态栏融合,需要借助android:fitsSystemWindows 这个属性来实现。在CoordinatorLayout 、AppBarLayout 、CollapsingToolbarLayout 这种嵌套结构的布局中,将控件的android:fitsSystemWindows 属性指定成true, 就表示该控件会出现在系统状态栏里。对应到我们的程序,那就是水果标题栏中的ImageView 应该设置这个属性了。不过只给Image View 设置这个属性是没有用的,我们必须将ImageView 布局结构中的所有父布局都设置上这个属性才可以。

将android:fitsSystemWindows 属性都设置好了还是没有用的,因为还必须在程序的主题中将状态栏颜色指定成透明色才行。指定成透明色的方法很简单,在主题中将
android:statusBarColor 属性的值指定成@android:color/transparent 就可以了。

上一篇:Android开发--FloatingActionButton/Snackbar/CoordinatorLayout 下一篇:Android之文字描边