Android下的沉浸式状态栏+折叠TitleBar(CoordinatorLayout+CollapsingToolbarLayout)+ViewPager切换实现

Android下的沉浸式状态栏+折叠TitleBar(CoordinatorLayout+CollapsingToolbarLayout)+ViewPager切换实现


最终效果以及过程中出现的问题如下:(简单解决在ViewPager+Fragment的组合中实现该效果时出现有页面视图偏移一个状态栏高度问题)

                                                                                                                 
           
 
一:实现沉浸式的状态栏
    沉浸式状态栏的实现是从android版本KITKAT开始,从KITKAT开始谷歌开始支持状态栏的背景色设置为透明,但在Lollipop版本(5.0)之后概念有所不同。
 设置状态栏透明的步骤:

1.实现当前activity的theme样式为无Tilte的,否则会有系统的titlebar显示在屏幕上方影响效果。
    即在Style.xml文件里面自定义一个主题样式:AppNoTitleTheme
    主要添加条目属性字段:windowNoTitletrue。并把要实现沉浸样式的Activity或整个应用的theme设置为该style 
     
     
     
  1. android:theme="@style/AppNoTitleTheme"
AppNoTitleTheme 对应如下:
     
     
     
  1. <style name="AppNoTitleTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  2. <!-- Customize your theme here. -->
  3. <item name="colorPrimary">@color/colorPrimary</item>
  4. <item name="windowNoTitle">true</item>
  5. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  6. <item name="colorAccent">@color/colorAccent</item>
  7. </style>
 
当然也可以直接引用系统预定义的 样式:
     
     
     
  1. android:theme="@style/Theme.AppCompat.Light.NoActionBar"
2.是实现状态栏的背景为透明背景,实现可以看到状态栏下方的视图内容,该实现一般在Activity中代码添加FLAG实现
   
   
   
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  4. this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//此FLAG可使状态栏透明,且当前视图在绘制时,从屏幕顶端开始即top = 0开始绘制,这也是实现沉浸效果的基础
  5. this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//可不加
  6. }
  7. setContentView(R.layout.activity_main);//在此之前添加以上FLAG
  8. initView();
  9. initEvent();
  10. }
tip:该FLAG需要在Activity 的setContentView(R.layout.activity_main)方法之前添加
加上此段代码之后在KITKAT及之上的版本即可实现状态栏透明,并且当前要展示的视图view从top为0的地方开始绘制。

至此状态栏已经实现透明,且当前的Activity视图已经可以延伸到状态栏下方
效果如下:


该效果实现之后有如下问题:此时标题会随整个试图的延伸一起延伸到状态栏的下方,致使状态栏遮挡了部分自定义的标题
解决该问题,也很简单android原生已经提供了相关实现:
要想实现标题栏不被遮挡,可以在在根节点的布局文件中添加fitsSystemWindows clipToPadding的标志位即可。代码如下:
   
   
   
  1. <RelativeLayout
  2. android:fitsSystemWindows="true"
  3. android:clipToPadding="false"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"></RelativeLayout>

fitsSystemWindows:该属性值表示系统布局过程中是否会为该view自动适应系统窗口(状态栏/导航栏),为true时系统会在设置了该属性的view的布局中,自动为其添加状态栏的高度的paddingtop值,使其实际布内容不被状态栏遮挡;为false时,则不会为其添加该padding值。默认不设的值为false。

clipToPadding:该属性值为在绘制的时候是否可以在其padding区域内绘制。当为true时可以在其padding区域内绘制,否则不可绘制。
》》但此时效果如下:虽然视图沉了一个状态栏的高度,但是同时状态栏的颜色是透明的,显示出了原有的底色。

此时,需要解决的是让状态栏下的颜色为自定义的,在版本为Lollipop及之后s状态栏可以设置背景色,但是KITKAT版本并没有此方法,这也是KITKAT只是设置状态栏背景为透明是相关的。所以KITKAT版本相比Lollipop及更高版本的沉浸实现是有一定差别。对此常用的解决方法就是
不再添加fitSystemwindows属性,而是手动添加一个占位布局,设置其高度为statusbar的高度,背景为设置为自己想要的颜色即可。

进一步,如果要实现底层背景是整张图片,并以该图片为背景色,需要其整个延伸至状态栏下方,则可做如下布局,同样在自定义的titlebar的布局上添加占位控件。设置其高度,同时设置其颜色为透明即可。
   
   
   
  1. <RelativeLayout
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent">
  4. <ImageView
  5. android:id="@+id/textdemo_image"
  6. android:src="@drawable/bg3"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent" />
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"
  12. android:orientation="vertical">
  13.                        
  14.                          <!-- textdemo_titleholderview 此控件为占位控件设置其高度为状态栏的高度-->
  15.     <View
  16.     android:id="@+id/textdemo_titleholderview"
  17.     android:layout_width="match_parent"
  18.     android:layout_height="0dp" />
  19.                          <!-- titlebar_view此控件为自定义的标题栏titlebar-->
  20.     <include layout="@layout/titlebar_view"></include>
  21. <View
  22. android:layout_width="match_parent"
  23. android:layout_height="0dp"
  24. android:layout_weight="1" />
  25. <LinearLayout
  26. android:layout_width="match_parent"
  27. android:layout_height="wrap_content"
  28. android:orientation="vertical">
  29. <include layout="@layout/line_mode_view"></include>
  30. <include layout="@layout/line_mode_view"></include>
  31. </LinearLayout>
  32. </LinearLayout>
  33. </RelativeLayout>
占位控件代码实现如下:
   
   
   
  1. ViewGroup.LayoutParams layoutParams = titlebarHolder.getLayoutParams();//titlebarHolder为添加的顶部的(标题栏上方)占位控件
  2. layoutParams.height = getStatueBarHeight();
  3. titlebarHolder.setLayoutParams(layoutParams);
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Linux下,可以通过自定义QWidget来实现自定义标题栏。具体实现步骤如下: 1. 创建一个继承自QWidget的类,用于实现自定义标题栏。 ```cpp class MyTitleBar : public QWidget { Q_OBJECT public: explicit MyTitleBar(QWidget *parent = nullptr); protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; private: QPoint m_lastPos; }; ``` 2. 在构造函数中设置标题栏的大小、背景色和布局。 ```cpp MyTitleBar::MyTitleBar(QWidget *parent) : QWidget(parent) { setFixedHeight(30); setStyleSheet("background-color: #333333"); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); setLayout(layout); } ``` 3. 重写mousePressEvent和mouseMoveEvent函数,实现标题栏的拖动。 ```cpp void MyTitleBar::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_lastPos = event->globalPos() - this->parentWidget()->geometry().topLeft(); } } void MyTitleBar::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { QPoint pos = event->globalPos() - m_lastPos; this->parentWidget()->move(pos); } } ``` 4. 在主窗口中添加自定义标题栏,并将系统标题栏隐藏。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setWindowTitle("Custom Title Bar"); setWindowFlags(Qt::FramelessWindowHint | windowFlags()); MyTitleBar *titleBar = new MyTitleBar(this); setMenuWidget(titleBar); // 添加其他控件及布局 // ... } ``` 5. 编译运行程序,即可看到自定义标题栏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值