实现开机动画和自定义Toolbar的高级写法

news2024/11/17 15:34:56

需求是自定义一个Toolbar和全屏展示一个第一次激活App的开机动画

1自定义Toolbar的使用

在这里插入图片描述

1仍然是先将工程的theme.xml中设置成NoActionBar

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.Animination" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>
        <item name="colorOnSecondary">@color/black</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>


</resources>

2在layout目录下自定义Toolbar布局,便于其他布局直接引用

toolbar_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="#E66161">
    
</androidx.appcompat.widget.Toolbar>

3在主布局中加入自定义的toolbar

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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=".MainActivity"
    android:orientation="vertical">
    
    <include layout="@layout/toolbar_layout"/>
    
    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="弹出dialog"/>
    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="弹出自定义动画"/>

</LinearLayout>

4在menu目录下设置toolbar上面的小控件

main,xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/backup"
        android:icon="@drawable/baseline_filter_drama_24"
        android:title="Backup"
        app:showAsAction="always"/>
    <item
        android:id="@+id/delete"
        android:icon="@drawable/baseline_delete_24"
        android:title="Delete"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/setting"
        android:icon="@drawable/baseline_settings_24"
        android:title="Settings"
        app:showAsAction="never"/>

</menu>

5通过实现接口的方式自定义ToolBarManager接口,并引入当前控件的menu

package com.njupt.animination.util

import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import com.njupt.animination.R

interface MyToolbarManager {
    val toolbar:Toolbar
    fun initMainToolBar(){
        toolbar.title="影音App"

        toolbar.inflateMenu(R.menu.main)

        //对里面的按钮进行点击事件的绑定
        toolbar.setOnMenuItemClickListener(object :Toolbar.OnMenuItemClickListener{
            override fun onMenuItemClick(item: MenuItem?): Boolean {
                when(item?.itemId){
                    R.id.backup->{
                        Toast.makeText(toolbar.context,"点击备份按钮",Toast.LENGTH_SHORT).show()
                    }
                    R.id.delete->{
                        Toast.makeText(toolbar.context,"点击删除按钮",Toast.LENGTH_SHORT).show()
                    }
                    R.id.setting->{
                        Toast.makeText(toolbar.context,"点击设置按钮",Toast.LENGTH_SHORT).show()
                    }
                }
                return true
            }

        }
        )

    }
}

6在需要使用到ToolBar的布局主类中实现接口

package com.njupt.animination

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.widget.Toolbar
import com.njupt.animination.util.MyToolbarManager

class MainActivity : AppCompatActivity() ,MyToolbarManager{
    override val toolbar: Toolbar by lazy {
        findViewById(R.id.toolbar)
    }
    private val mdialog:MyDiaglog by lazy {
        MyDiaglog(this,R.style.dialog)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //调用MyToolbarManager接口里的方法来初始化toolbar
        initMainToolBar()

        val btn=findViewById<Button>(R.id.btn1)
        btn.setOnClickListener(){
            mdialog.show()
        }
        val btn2=findViewById<Button>(R.id.btn2)
        btn2.setOnClickListener(){
            startActivity(Intent(this,SplashActivity::class.java))
        }

    }
}

2App初始动画

一般是一张图片进行动态的展示后显示出主布局,所以真正使用时将进入界面设置成当前界面,全屏显示的效果,没有ActionBar,也没有系统标题。
在这里插入图片描述

1界面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/image_splash"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/splash"
        android:scaleType="centerCrop"
        android:scaleX="1.5"
        android:scaleY="1.5"/>

</LinearLayout>

2主程序实现

package com.njupt.animination

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.ViewPropertyAnimatorListener

class SplashActivity:AppCompatActivity(), ViewPropertyAnimatorListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //实现全屏显示
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
        
        setContentView(R.layout.splash_activity)
        var splashImage=findViewById<ImageView>(R.id.image_splash)
        //结束动画之后添加一个结束动画监听事件,结束后自动调转到App首页
        ViewCompat.animate(splashImage).scaleX(1.0f).scaleY(1.0f).setListener(this).setDuration(1000)
    }

    override fun onAnimationStart(view: View?) {

    }

    override fun onAnimationEnd(view: View?) {
        startActivity(Intent(this,SplashOverActivty::class.java))
    }

    override fun onAnimationCancel(view: View?) {

    }
}

3自定义的toolbar中点击设置按钮跳转到设置界面

在这里插入图片描述

1PreferenceFragment废弃问题需要使用到PreferenceFragmentCompat

加入依赖

implementation 'androidx.preference:preference:1.0.0'

2点击自定义的设置按钮后进行界面的跳转

package com.njupt.animination.util

import android.content.Intent
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import com.njupt.animination.R
import com.njupt.animination.ui.activity.SettingActivity

interface MyToolbarManager {
    val toolbar:Toolbar
    fun initMainToolBar(){
        toolbar.title="影音App"

        toolbar.inflateMenu(R.menu.main)

        //对里面的按钮进行点击事件的绑定
        toolbar.setOnMenuItemClickListener(object :Toolbar.OnMenuItemClickListener{
            override fun onMenuItemClick(item: MenuItem?): Boolean {
                when(item?.itemId){
                    R.id.backup->{
                        Toast.makeText(toolbar.context,"点击备份按钮",Toast.LENGTH_SHORT).show()
                    }
                    R.id.delete->{
                        Toast.makeText(toolbar.context,"点击删除按钮",Toast.LENGTH_SHORT).show()
                    }
                    R.id.setting->{
                        //Toast.makeText(toolbar.context,"点击设置按钮",Toast.LENGTH_SHORT).show()
                        //点击设置按钮之后跳转到设置的界面
                        toolbar.context.startActivity(Intent(toolbar.context,SettingActivity::class.java))
                    }
                }
                return true
            }

        }
        )

    }

//设置界面需要的自定义toolbar
    fun initSettingToolbar(){
        toolbar.title="设置"
    }
}

3设置界面实现toolBar的接口,设置当前toolbar

package com.njupt.animination.ui.activity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.preference.PreferenceManager
import com.njupt.animination.R
import com.njupt.animination.util.MyToolbarManager

class SettingActivity:AppCompatActivity() ,MyToolbarManager{
    override val toolbar: Toolbar by lazy {
        findViewById(R.id.toolbar)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.setting_activity)
        initSettingToolbar()

        val sp=PreferenceManager.getDefaultSharedPreferences(this)
        val push=sp.getBoolean("push",false)
        println(push)


    }
}

4自定义fragment,在fragment中继承PreferenceFragmentCompat

package com.njupt.animination.ui.fragment

import android.os.Bundle
import android.preference.PreferenceFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.njupt.animination.R

class SettingFragment: PreferenceFragmentCompat() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        addPreferencesFromResource(R.xml.setting)
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

    }

    override fun onPreferenceTreeClick(preference: Preference?): Boolean {
        when(preference?.key){
            "clear"->{Toast.makeText(this.context,"点击了按钮",Toast.LENGTH_SHORT).show()}
        }
        return super.onPreferenceTreeClick(preference)
    }
}

5R.xml.setting设置当前设置的选项和按钮等

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <Preference
        android:key="clear"
        android:title="清除缓存"/>

    <SwitchPreference
        android:key="push"
        android:title="推送通知"
        />
    <SwitchPreference
        android:key="no_wifi"
        android:title="非wifi下加载图片"
        />
    <PreferenceCategory
        android:title="第一类">
        <Preference
            android:key="clear1"
            android:title="清除缓存1"/>
        <Preference
            android:key="clear2"
            android:title="清除缓存2"/>

    </PreferenceCategory>


    <DropDownPreference
        android:title="加载视频"/>
    <Preference
        android:key="about"
        android:title="关于"/>

    <PreferenceCategory android:title="显示一排偏好">
        <CheckBoxPreference android:key="checkbox_preference" android:title="开关偏好" android:summary="这是一个开关按钮" />
    </PreferenceCategory>
    <PreferenceCategory android:title="基于对话框的偏好">
        <EditTextPreference android:key="edittext_preference" android:title="文本输入偏好" android:summary="使用一个文本框对话框" android:dialogTitle="输入你的宠物" />
    </PreferenceCategory>
    <PreferenceCategory android:title="启动偏好">
        <PreferenceScreen android:key="screen_preference" android:title="屏幕" android:summary="显示另一个偏好屏幕">
            <!-- You can place more preferences here that will be shown on the next screen. -->
            <CheckBoxPreference android:key="next_screen_checkbox_preference" android:title="开关偏好" android:summary="另一个屏幕上的偏好" />
        </PreferenceScreen>
        <PreferenceScreen android:title="意图偏好" android:summary="通过意图启动一个Activity">
            <intent android:action="android.intent.action.VIEW" android:data="http://www.android.com"/>
        </PreferenceScreen>
    </PreferenceCategory>
    <PreferenceCategory android:title="偏好属性">
        <CheckBoxPreference android:key="parent_checkbox_preference" android:title="父开关" android:summary="这是一个父开关" />
        <CheckBoxPreference android:key="child_checkbox_preference" android:dependency="parent_checkbox_preference" android:layout="?android:attr/preferenceLayoutChild" android:title="子开关" android:summary="这是一个子开关" />
    </PreferenceCategory>

</PreferenceScreen>

在这里插入图片描述

6设置的主布局中加入fragment

setting_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <include layout="@layout/toolbar_layout"/>

    <!--需要在加一个Fragment-->
    <fragment
        android:id="@+id/setting_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.njupt.animination.ui.fragment.SettingFragment"/>

</LinearLayout>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle11g全新讲解之PLSQL编程

一、PLSQL编程 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言.通过增加变量、控制语句&#xff0c;使我们可以写一些逻辑更加复杂的数据库操作. 语法结构 declare--声明变量 变量名称 v_ 开头&#xff0c;规范 begin--执行具体的语句--异常处理 …

Spring原理学习(五):一篇讲清楚动态代理(jdk和cglib)的使用、原理和源码

目录 一、jdk动态代理的基本使用 二、cglib动态代理的基本使用 2.1 方法一&#xff1a;method.invoke() 方法反射调用 2.2 方法二&#xff08;spring使用的这个方法&#xff09;&#xff1a; methodProxy.invoke() 2.3 方法三&#xff1a;methodProxy.invokeSuper() 三、…

(Linux驱动入门)字符设备

一、设备相关概念 1.1 设备号 内核中通过类型dev_t来描述设备号&#xff0c;其实质是unsigned int 32位整数&#xff0c;其中高12位为主设备号&#xff0c;低20位为次设备号。设备号也是一种资源&#xff0c;当我们需要时可以调用函数去申请。 ​​​​​​​int register_c…

光伏发电数据监控的运维平台

摘要&#xff1a;全球化经济社会的快速发展,加快了传统能源的消耗,导致能源日益短缺,与此同时还带来了严重的环境污染。因此,利用没有环境污染的太阳能进行光伏发电获得了社会的普遍关注。本文根据传统式光伏电站行业的发展背景及其监控系统的技术设备,给出了现代化光伏电站数据…

Vue3通透教程【十二】TS类型声明优势

文章目录 &#x1f31f; 写在前面&#x1f31f; 上篇文章解惑&#x1f31f; JS函数中的隐患&#x1f31f; 函数中的类型&#x1f31f; 写在最后 &#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 V…

计算机视觉 | 八斗人工智能 (中)

目录 卷积&滤波1.一个没有任何效果的卷积核2.平均均值滤波3.图像锐化4.soble边缘检测 卷积的三种填充模式1.padding --> same模式 最常用的模式2.full和valid模式三通道卷积 canny边缘检测算法&#xff08;效果最好&#xff09;Sobel算子、Prewitt算子 相机模型畸变矫正…

新能源汽车和数字化转型

工业时代的代表产品是交通运输设备&#xff0c;核心桂冠是发动机。信息时代的代表产品是智能手机&#xff0c;核心桂冠是芯片。 汽车是个很有代表性产品&#xff0c;因为它既属于复杂高精密金属机械设备&#xff0c;又属于大规模使用的大件消费品。所以这100年来&#xff0c;汽…

代码随想录算法训练营第三十二天|122.买卖股票的最佳时机II 、55. 跳跃游戏 、45.跳跃游戏II

文章目录 122.买卖股票的最佳时机II55. 跳跃游戏45.跳跃游戏II:star: 122.买卖股票的最佳时机II 遇到每天正利润就收集&#xff0c;负利润就不收集 链接:代码随想录 解题思路&#xff1a; ①因为可以多次买卖&#xff0c;所以考虑到最终把最终利润进行分解 如假如第0天买入&am…

垃圾收集算法面试总结

垃圾收集算法 标记 - 清除算法 首先标记出所有需要被回收的对象&#xff0c;标记完后统一回收所有被标记的对象。 后续的收集算法都是基于这种思路并对其不足进行改进而得到的。 这种方法主要有两个缺点&#xff1a; 一个是效率问题&#xff0c;标记和清除两个过程的效率都…

java mysql超市会员积分带抽奖系统

后台相关操作&#xff1a; &#xff08;1&#xff09;系统管理&#xff1a;管理系统的管理员用户。 &#xff08;2&#xff09;会员管理&#xff1a;对会员信息进行增删改功能。 &#xff08;3&#xff09;商品管理&#xff1a;对系统的商品进行增删改查功能等维护。 &#xff…

分治法解二维的最近对问题,算法分析与代码实现,蛮力法与分治法解决二维的最近对问题的区别

&#x1f38a;【数据结构与算法】专题正在持续更新中&#xff0c;各种数据结构的创建原理与运用✨&#xff0c;经典算法的解析✨都在这儿&#xff0c;欢迎大家前往订阅本专题&#xff0c;获取更多详细信息哦&#x1f38f;&#x1f38f;&#x1f38f; &#x1fa94;本系列专栏 -…

人工智能发展到GPT4经历了什么,从专家系统到机器学习再到深度学习,从大模型到现在的GPT4

大家好&#xff0c;我是微学AI&#xff0c;今天给大家讲一下人工智能的发展&#xff0c;从专家系统到机器学习再到深度学习&#xff0c;从大模型到现在的GPT4&#xff0c;讲这个的目的是让每个人都懂得人工智能&#xff0c;每个人都懂得人工智能的发展&#xff0c;未来人工智能…

“智慧赋能 强链塑链”—— 煤炭行业数字化转型探讨

煤炭作为传统能源行业之一&#xff0c;是国民经济中不可或缺的一部分&#xff0c;随着国家能源结构的战略转型&#xff0c;煤炭企业的长期盈利能力将面临巨大的挑战。供应链作为煤炭行业生产运营的基础保障&#xff0c;在企业开源节流的要求下&#xff0c;其传统粗放的供应链管…

Xcode 14.3 cocoapod 1.12.0 打包报错解决

前言 前几天升级Xcode到14.3版本&#xff0c;运行项目报错&#xff0c;于是记录下来。 开发环境 macOS: 13.3.1 Xcode: 14.3 CocoaPods: 1.12.0 问题描述 [Xcode菜单栏] -> [Product] -> [Archive]&#xff0c;进行打包操作。执行到 Run custom shell script [CP]…

day16 信号灯

信号灯概念和有名信号灯 目录 信号灯概念和有名信号灯 有名信号灯 无名信号灯 信号灯P操作 信号灯V操作 system V信号灯的 信号灯/信号量&#xff08;semaphore&#xff09; 信号量代表某一类资源&#xff0c;其值表示系统中该资源的数量&#xff1b; 信号量是一个受保…

【C语言】程序运行环境及预处理指令

文章目录 程序的翻译环境&#xff1a;程序的运行环境&#xff1a;C语言预定义符号#define定义标识符#define定义宏具有副作用的宏参数 #与###的使用##的使用 宏和函数对比#undef命令行定义条件编译常见的条件编译指令&#x1f31e; 文件包含指令嵌套文件包含 其他预处理指令 撒…

【C++】对数组指针的理解,例如 int (*p)[3]

目录 简介思考理解结语 简介 Hello&#xff01; 非常感谢您阅读海轰的文章&#xff0c;倘若文中有错误的地方&#xff0c;欢迎您指出&#xff5e; ଘ(੭ˊᵕˋ)੭ 昵称&#xff1a;海轰 标签&#xff1a;程序猿&#xff5c;C选手&#xff5c;学生 简介&#xff1a;因C语言结识…

Win7 无法安装 VMware Tools 解决方法

文章目录 1.下载kb4474419补丁2.虚拟机 > 设置 > 软盘&#xff0c;选中“使用物理驱动器”3.解决IE浏览器只能访问百度4.下载windows iso的正确方式 win7版本&#xff1a;cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408_2&#xff08;iso大小3.18 GB&#xff09; vmwa…

C++内联函数(编译器角度,汇编角度),auto关键字,范围for语法糖,nullprt与NULL区别等

TIPS 在C当中有一个东西可以打印类型&#xff1f;typeid(变量名).name()数组一旦从参数进入到函数里面&#xff0c;它就已经是个指针了&#xff0c;再也不是一整个数组了 内联函数&#xff08;正常函数定义前加个inline修饰&#xff09; 在实际当中&#xff0c;有时候去调用…

13、拦截器

文章目录 1、HandlerInterceptor 接口2、配置拦截器3、拦截器原理 【尚硅谷】SpringBoot2零基础入门教程-讲师&#xff1a;雷丰阳 笔记 路还在继续&#xff0c;梦还在期许 1、HandlerInterceptor 接口 /*** 登录检查* 1、配置好拦截器要拦截哪些请求* 2、把这些配置放在容器中…