【Android实战】Android沉浸式状态栏实现(下)

之前的Android沉浸式状态栏实现并没有考虑软键盘的影响,接下来的内容将会针对这个问题给出解决方式,先看一下效果图

这个是一个留言板的效果图:

即弹出软键盘的时候并不会导致整个布局上移。

详细怎样实现?依照下面步骤进行设置:

1、布局文件里声明例如以下

 <activity
            android:name="com.storm.durian.activity.LeaveMessageDetailsActivity"
            android:screenOrientation="portrait"
            />

2、这里重写了RelativeLayout。并重写了fitSystemWindows,这个是最最关键的。

/**
 * 自适应布局
 */
public class FitsSystemWindowsLayout extends RelativeLayout {
    private static final String TAG = FitsSystemWindowsLayout.class.getSimpleName();
    private SoftKeyBoardStateListener softKeyBoardStateListener;

    public FitsSystemWindowsLayout(Context context) {
        super(context);
    }

    public FitsSystemWindowsLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FitsSystemWindowsLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {

        dispatchListenerLow(heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 处理低版本号键盘弹出
     *
     * @param heightMeasureSpec 高度
     */
    private void dispatchListenerLow(int heightMeasureSpec) {
        if (softKeyBoardStateListener == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            return;
        }
        int oldSpec = getMeasuredHeight();

        if (oldSpec <= 0) {
            return;
        }
        int newSpec = MeasureSpec.getSize(heightMeasureSpec);
        int offset = oldSpec - newSpec;
        if (offset > 100) {
            LogHelper.i(TAG, "键盘打开");
            softKeyBoardStateListener.onSoftKeyBoardStateChange(true);
        } else if (offset < -100) {
            LogHelper.i(TAG, "键盘关闭");
            softKeyBoardStateListener.onSoftKeyBoardStateChange(false);
        }
    }

    @Override
    protected boolean fitSystemWindows(Rect insets) {
        dispatchListener(insets);
        insets.top = 0;
        return super.fitSystemWindows(insets);
    }

    /**
     * 分发监听
     *
     * @param insets
     */
    private void dispatchListener(Rect insets) {
        if (softKeyBoardStateListener == null || android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        if (insets.top != 0 && insets.bottom != 0) {
            LogHelper.i(TAG, "键盘打开");
            softKeyBoardStateListener.onSoftKeyBoardStateChange(true);
        } else {
            LogHelper.i(TAG, "键盘关闭");
            softKeyBoardStateListener.onSoftKeyBoardStateChange(false);
        }

    }

    /**
     * 设置软键盘监听事件
     *
     * @param softKeyBoardStateListener
     */
    public void setSoftKeyBoardListener(SoftKeyBoardStateListener softKeyBoardStateListener) {
        this.softKeyBoardStateListener = softKeyBoardStateListener;
    }

    public interface SoftKeyBoardStateListener {

        public void onSoftKeyBoardStateChange(boolean isOpen);

    }
}

尽管以上布局也提供了键盘打开或者关闭的回调,可是在某些低版本号手机上还是支持的不太好,须要这个回调的能够将此回调作为当中一个方法。可是不要过分依赖

3、布局文件

使用com.storm.durian.view.FitsSystemWindowsLayout包裹整个布局,并设置android:fitsSystemWindows=“true”

<?xml version="1.0" encoding="utf-8"?

>
<com.storm.durian.view.FitsSystemWindowsLayout android:id="@+id/leave_message_layout"
                                               xmlns:android="http://schemas.android.com/apk/res/android"
                                               android:layout_width="match_parent"
                                               android:layout_height="match_parent"
                                               android:background="@color/ececec"
                                               android:fitsSystemWindows="true">

    <include
        android:id="@+id/leave_message_title"
        layout="@layout/common_back"/>

    <LinearLayout
        android:id="@+id/ll_leave_message_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@drawable/leave_message_bottom_bg"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_leave_message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="3"
            android:background="@drawable/et_leave_message_bg"
            android:hint="亲,给我留言我会回复你哒~"
            android:maxLines="4"
            android:textColor="@color/_3e363d"
            android:textSize="@dimen/text_size_small"/>

        <Button
            android:id="@+id/btn_leave_message_send"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_weight="1"
            android:background="@drawable/btn_leave_message_send_selector"
            android:singleLine="true"
            android:text="发送"
            android:textColor="@color/_3e363d"
            android:textSize="@dimen/text_size_middle"/>
    </LinearLayout>

    <ListView
        android:id="@+id/lv_leave_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/ll_leave_message_input"
        android:layout_below="@id/leave_message_title"
        android:cacheColorHint="#00000000"
        android:divider="@color/dbdbdb"
        android:dividerHeight="1dp"
        android:fadingEdge="none"/>

    <ViewStub
        android:id="@+id/activity_leave_message_loading_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/leave_message_title"
        android:inflatedId="@+id/activity_leave_message_loading_subTree"
        android:layout="@layout/common_loading"/>

    <ViewStub
        android:id="@+id/leave_message_empty_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/ll_leave_message_input"
        android:layout_below="@id/leave_message_title"
        android:inflatedId="@+id/leave_message_empty_subTree"
        android:layout="@layout/common_tips_layout"/>

    <ViewStub
        android:id="@+id/leave_message_net_error_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/leave_message_title"
        android:inflatedId="@+id/leave_message_net_error_subTree"
        android:layout="@layout/common_net_error_layout"/>

</com.storm.durian.view.FitsSystemWindowsLayout>

4、Activity中处理

设置setImmerseLayout(findViewById(R.id.leave_message_title));

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_leave_detail_message);
        setImmerseLayout(findViewById(R.id.leave_message_title));
        logic = LeaveMessageLogic.getInstance(getApplicationContext());
        mHandler = new MyHandler(this);
        initView();
    }

再看BaseActivity中的setImmerseLayout方法

版本号要求仍然是4.4以上

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        isStart = true;
        ShareSDK.initSDK(this);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            statusBarHeight = ScreenUtil.getStatusBarHeight(this);
        }
        ScreenManager.getScreenManager().pushActivity(this);
    }
   protected void setImmerseLayout(View view) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Window window = getWindow();
                window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
               // window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

            int statusBarHeight = ScreenUtil.getStatusBarHeight(this.getBaseContext());
            view.setPadding(0, statusBarHeight, 0, 0);
        }
    }

OK。须要的朋友们能够自己尝试一下!

有空的话会将这个沉浸式的留言板的功能写一下分享出来!

时间: 2024-12-15 11:53:42

【Android实战】Android沉浸式状态栏实现(下)的相关文章

Android中的沉浸式状态栏效果

无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定程度上牺牲了视觉宽度,界面面积变小.Google从android kitkat(Android 4.4)开始,给我们开发者提供了一套能透明的系统ui样式给状态栏和导航栏,这样的话就不用向以前那样每天面对着黑乎乎的上下两条黑栏了,还可以调成跟Activity一样的样式,形成一个完整的主题,和IOS7.

Android 4.4沉浸式状态栏的实现

要实现Android 4.4上面的沉浸式状态栏要用到开源项目SystemBarTint(https://github.com/hexiaochun/SystemBarTint) public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.

android沉浸式状态栏实现

传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这样就在一定程度上牺牲了视觉宽度,界面面积变小. 沉浸模式的状态栏和主界面完全融为了一体,在设计上有不同的视觉感受. 我们先上两张图,很容易看出区别:        Android在4.4的时候增加了透明状态栏与导航栏的功能,依托于这个新特性,我们可以开始跟随潮流,实现Android的沉浸式状态栏 其实上图展示的这个关于界面的代码非常简单 /** * 关于界面 * * @author SuS * @time 2015.07.29

Android 沉浸式状态栏

效果图 android 5.0 以上 android 4.4 API 19 以上都是原生安卓系统的效果,具体到国内的各种各样改过的系统可能会有细微差别,测试过小米和华为的机器效果基本一样. 实现 1.修改主题属性 方法一: 在values-v19文件夹下声明AppTheme为透明状态栏,代码如下 1 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 2 <!-- C

81.Android之沉浸式状态栏攻略

转载:http://blog.csdn.net/lmj623565791/article/details/48649563/ 一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图: 关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去 为什么在国内会有很多用户把 ?透明栏?(Translucent Bars)称作 ?沉浸式顶栏??上面了解了解,请勿指点我说的博文标题起得不对,thx. 恩,接下来正题. 首先只有大

教程分享:如何实现Android沉浸式状态栏——教你让你的状态栏变个色!

一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图: 关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去了解下. 恩,接下来正题. 首先只有大于等于4.4版本支持这个半透明状态栏的效果,但是4.4和5.0的显示效果有一定的差异,所有本篇博文内容为: 如何实现半透明状态栏效果在大于4.4版本之上. 如何让4.4的效果与5.0的效果尽可能一致. 看了不少参考文章,都介绍到这个库,大家可以了解:SystemBarT

Android 沉浸式状态栏攻略 让你的状态栏变色吧

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/48649563: 本文出自:[张鸿洋的博客] 一.概述 近期注意到QQ新版使用了沉浸式状态栏,ok,先声明一下:本篇博客效果下图: 关于这个状态栏变色到底叫「Immersive Mode」/「Translucent Bars」有兴趣可以去 为什么在国内会有很多用户把 ?透明栏?(Translucent Bars)称作 ?沉浸式顶栏??上面了解了解,请勿指点我说的博文标题起得不对

Android 实现沉浸式状态栏

上一篇文章将Android 实现变色状态栏我们实现了变色的状态栏,也介绍了沉浸式状态栏和透明状态栏的区别,这篇文章我们实现沉浸式状态栏. 沉浸式状态栏的来源就是很多手机用的是实体按键,没有虚拟键,于是开了沉浸模式就只有状态栏消失了.于是沉浸模式成了沉浸式状态栏. 我们先来看下具体的效果 开启沉浸模式后,状态栏消失,从顶部向下滑动,状态栏出现,退出沉浸模式,状态栏也出现了. 我们的代码基于前一篇文章.首先是两个开启沉浸模式和关闭沉浸模式的函数 @SuppressLint("NewApi"

Android设置沉浸式状态栏时改变状态栏的颜色(只对MIUI V6可用)

Android支持在API 19及以上使用沉浸式状态,但在MIUI V6下如果扩展的颜色比较浅,会导致状态栏的文字无法看清. 在Android4.4设备上支持沉浸式状态栏,只需要添加values-v19/styles.xml 下添加 <style name="AppBaseTheme" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="android:window