精华内容
下载资源
问答
  • Android app启动页广告

    热门讨论 2016-12-15 10:26:22
    Android app启动也得广告,时间倒计时,支持跳过。详情见博客:http://blog.csdn.net/u010918416/article/details/52924930
  • 仿写了几种App启动欢迎页面 很实用 很漂亮 包含了常见的几种启动画面
  • android仿腾讯视频启动页及广告页面动画效果实现
  • app启动页 博客地址:http://blog.csdn.net/lowprofile_coding/article/details/51170252
  • Flutter 启动页 消除白屏

    万次阅读 多人点赞 2019-07-09 16:36:52
    文章目录Android 启动页IOS 任何一个app基本都会设计一个启动页,今天我们就来看看怎么在flutter项目中设置启动页。 开始的时候我的第一个想法就是把启动页当成一个Widget,先加载这个Widget然后在显示我们的主...

    文章目录


    任何一个app基本都会设计一个启动页,今天我们就来看看怎么在flutter项目中设置启动页。
    开始的时候我的第一个想法就是把启动页当成一个Widget,先加载这个Widget然后在显示我们的主页面,可是在实践的过程中遇到一个很大的问题,app启动的时候会出现较长时间的白屏,在android手机上很明显,而且性能越差时间越长,ios相对好些。做过android原生开发的都知道android原生也有白屏问题,不过flutter要明显的多,如何解决这个问题?其实我们在创建flutter项目的时候,系统已经帮我们解决了,只不过我们没有注意到而已。

    Android 启动页

    首先打开如下图的文件:
    在这里插入图片描述
    有这么一段
    在这里插入图片描述
    meta-data 中value设置为true代表有启动页,然后打开res->values->style.xml文件如下图:
    在这里插入图片描述
    文件中设置了style,名称为LaunchTheme,注意这个名称不能修改,style加载的是drawable中的launch_background.xml,我们打开这个文件:
    在这里插入图片描述

    默认情况下红框内的item是没有的,这就是我们要设置的启动页的图片,启动页的图片我们存放在drawable下,如下图:
    在这里插入图片描述
    到这里android启动页就是设置完成了。

    IOS

    打开如下目录:
    在这里插入图片描述
    将LaunchImage.png、LaunchImage@2x.png、LaunchImage@3x.png 替换为我们自己启动页图片即可。

    Flutter 系列文章

    展开全文
  • react-native设置应用启动页

    万次阅读 2018-07-29 12:35:25
    在我们使用react-native进行编写代码的时候,当启动应用的时候,我们会看到如下界面 然而,这样的启动界面是非常的不又好,那么我们该怎么进行处理启动界面呢?有如下两种方案 二、方案 1.使用第三方库...

    一、背景

    在我们使用react-native进行编写代码的时候,当启动应用的时候,我们会看到如下界面




    然而,这样的启动界面是非常的不又好,那么我们该怎么进行处理启动界面呢?有如下两种方案

    二、方案

    • 1.使用第三方库(react-native-splash-screen)
    • 2.ios系统设置(仅适用ios系统,在这里不做讲解)

    三、具体实现方式

    一).react-native-splash-screen
    1.安装
    npm i react-native-splash-screen --save
    2.链接到底层代码

    1.自动配置链接

        react-native link react-native-splash-screen

    or

        rnpm link react-native-splash-screen

    2.手动配置链接
    Android手动配置:

    (1)在android/settings.gradle文件中添加如下代码:

    include ':react-native-splash-screen'
    project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
    

    (2) 在android/app/build.gradle文件中,dependencies对象内添加如下代码:

      dependencies {
          ...
          compile project(':react-native-splash-screen')
          ...
      }
    

    (3)在 MainApplication.java文件中添加如下代码:

        import org.devio.rn.splashscreen.SplashScreenReactPackage;
        ...
          @Override
          protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                new MainReactPackage(),
                new SplashScreenReactPackage(), // 添加启动页代码
            );
          }

    以上就是android系统中链接的方式,下面是ios底层链接的方式
    ios手动配置:
    (1)在 XCode中, 点击项目,打开展开项目右键点击 Libraries ➜ Add Files to [your project's name],选中路径 node_modules ➜ react-native-splash-screen and add SplashScreen.xcodeproj添加SplashScreen.xcodeproj项目文件

    (2)在 XCode中, 点击项目,打开展开项目, 选中你的项目. 添加 libSplashScreen.a 到你的项目的 Build Phases ➜ Link Binary With Libraries中,界面如下所示:

    Xcode添加Link Binary With Libraries

    (3)修复 'SplashScreen.h' file not found, 选择你的项目 → Build Settings → Search Paths → Header Search Paths to add:

    $(SRCROOT)/../node_modules/react-native-splash-screen/ios

    界面如下所示:
    Build Settings
    以上就是ios系统的配置链接的方法,下面就让我们来看看具体在代码中的使用

    3.进行使用
    • android:
      (1)在MainActivity.java文件中添加如下代码:

       import android.os.Bundle; // here
       import com.facebook.react.ReactActivity;
       import org.devio.rn.splashscreen.SplashScreen; // 启动页设置添加代码
      
       public class MainActivity extends ReactActivity {
           /**
            * 设置启动页
            */
           @Override
           protected void onCreate(Bundle savedInstanceState) {
               SplashScreen.show(this);  // 展示启动页设置代码
               super.onCreate(savedInstanceState);
           }
           // ...other code
       }
      

      (2)添加启动页图片及布局
      在路径app/src/main/res/layout创建文件(如果不存在则进行手动创建)命名为 launch_screen.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"
         android:background="@drawable/launch_screen">
        </LinearLayout>

    (3)在res文件夹下面创建如下文件夹,添加对应分辨率图片,分别对应放入下面文件夹,图片命名和xml中一致,命名为launch_screen

             drawable-ldpi
             drawable-mdpi
             drawable-hdpi
             drawable-xhdpi
             drawable-xxhdpi
             drawable-xxxhdpi

    到这里,我们已经能够在界面中能够看到启动页的加载了,但是为了能有更好的效果,我们继续往下看,在文件夹app/src/main/res/values/colors.xml中添加一个颜色命名为status_bar_color ,其中status_bar_color为状态栏颜色设置,代码如下所示:

             <?xml version="1.0" encoding="utf-8"?>
             <resources>
                 <color name="status_bar_color">#FF0000</color>
             </resources>

    同时我们能够在启动的过程中看到有白屏出现,我们将启动背景设置成透明背景,使用下面方式进行处理, 打开android/app/src/main/res/values/styles.xml文件,并且添加 <item name="android:windowIsTranslucent">true</item>
    到文件中,添加之后结果如下所示:

             <resources>
                 <!-- Base application theme. -->
                 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
                     <!-- Customize your theme here. -->
                     <!--设置透明背景-->
                     <item name="android:windowIsTranslucent">true</item>
                 </style>
             </resources>

    当然,你也可以使用自定义的启动颜色,如下面所示:

    在路径android/app/src/main/res/values/colors.xml文件添加如下代码用于设置状态栏

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <color name="status_bar_color"><!-- Colour of your status bar here --></color>
    </resources>

    在路径android/app/src/main/res/values/styles.xml中添加自定义样式,代码如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name="SplashScreenTheme" parent="SplashScreen_SplashTheme">
            <item name="colorPrimaryDark">@color/status_bar_color</item>
        </style>
    </resources>

    然后修改启动页展示的样式选择就可以了:

    SplashScreen.show(this, R.style.SplashScreenTheme);

    效果如下所示,我们能够看到顶部红色的状态栏:



    [ios_lanch_screen_custom.gif]

    • ios:
      更新AppDelegate.m文件如下所示代码:
    #import "AppDelegate.h"
    
    #import <React/RCTBundleURLProvider.h>
    #import <React/RCTRootView.h>
    #import <React/RCTRootView.h>
    #import "RNSplashScreen.h"  // 导入启动页组件库
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      NSURL *jsCodeLocation;
    
      jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
    
      RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                          moduleName:@"LoveYouDeeply"
                                                   initialProperties:nil
                                                       launchOptions:launchOptions];
      rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
    
      self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
      UIViewController *rootViewController = [UIViewController new];
      rootViewController.view = rootView;
      self.window.rootViewController = rootViewController;
      [self.window makeKeyAndVisible];
      [RNSplashScreen show];  // 添加启动页展示
      return YES;
    }
    
    @end
    

    然后通过LaunchImage or LaunchScreen.xib自定义启动页,其具体过程如下所示,
    1、用Xcode打开ios工程,找到Image.xcassets并点击选中,在空白处选择 App Icons & Launch Images ➜ New ios Launch Image , 完成这步后会生成一个LaunchImage,操作界面如下所示:
    new iOS launch image
    2、选中Image.xcassets ➜ LaunchImage,就是上一步创建的LaunchImage,右侧框中的部分是让你选择要支持的系统,横竖屏之类的(这个按照需求选择,如果你的项目不打算支持ios6可以不选择)。然后点击中间部分选中一个分辨率的框,上传相应分辨率的图片作为启动屏幕

    以下是选择框中不同屏幕的分辨率,按照下面给出的像素进行制作特定大小的图片添加即可:

    iPhone Portrait iOS 8-Retina HD 5.51242×2208) @3x
    iPhone Portrait iOS 8-Retina HD 5.51242×2208) @3x
    iPhone Portrait iOS 8-Retina HD 4.7750×1334) @2x
    iPhone Portrait iOS 7,8-2x (640×960) @2x
    iPhone Portrait iOS 7,8-Retina 4640×1136) @2x
    iPhone Portrait iOS 5,6-1x (320×480) @1x
    iPhone Portrait iOS 5,6-2x (640×960) @2x
    iPhone Portrait iOS 5,6-Retina4 (640×1136) @2x

    3、选中LaunchScreen.xib,会有个弹出框,默认选择确定就行,然后把右边的 Use Launch Screen 取消选中(因为ios可以用来自定义图片启动屏幕或通过 LaunchScreen.xib启动屏幕,ios默认s设置,我们在这里取消掉默认设置的)。
    界面如下所示:
    remove location
    4、如图选中项目工程,右侧会出现工程的基本配置,设置Launch Images Srouce配置为LaunchImage(如果没有LaunchImage会弹出一个框提示拷贝图片,按照默认点确定就行),然后设置Launch Screen File为空(这个很重要)。

    现在,我们所有的准备工作都已经完成,下面就是在js代码中的使用,在React-Native代码中进行隐藏启动页,
    当我们准备好js代码之后,我们就可以将我们的启动页进行隐藏掉,其中隐藏启动页的代码如下所思:

    import React, { Component } from 'react';
    import SplashScreen from 'react-native-splash-screen';
    import Router from './src/routerManager';
    
    export default class App extends Component {
      constructor(props) {
        super(props);
          // do anything while splash screen keeps, use await to wait for an async task.
          // 在入口文件处隐藏掉启动页
          SplashScreen.hide(); // 关闭启动屏幕
      }
      render() {
        return (
          <Router {...this.props} />
        );
      }
    }

    在ios系统配置中,

    四、效果展示

    Android:




    以上就是启动页的设置解决方案

    展开全文
  • Android开发:APP引导页启动页小Demo(实例)

    万次阅读 多人点赞 2018-11-03 00:23:28
    从之前入门Android,一步一步的走到现在,过程真的难于...废话不多说,这次讲解APP的引导页启动页,我使用在代码中加入详细的注释的方式进行讲解,对于以下不经常出现的API我都进行了注解,接下来直接开始吧。 先...

    从之前入门Android,一步一步的走到现在,过程真的难于言表,只有经历过的人才知道吧,理解初学Android时痛苦,所以现在在Android上略窥门径的时候,回过头来写一些小Demo,希望能够帮助到需要的人,后面有空会经常写一些实例Demo。

    废话不多说,这次讲解APP的引导页启动页,我使用在代码中加入详细的注释的方式进行讲解,对于以下不经常出现的API我都进行了注解,接下来直接开始吧。

    先上效果图(PS:动态图没来得及做,时间好晚了,可以直接下载我的项目运行,附GitHub链接):

    java包如图:

     

    WelcomeActivity.java

    package com.example.power.welcomepage;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Bundle;
    import android.os.Handler;
    
    import com.example.power.welcomepage.Activity.MainActivity;
    import com.example.power.welcomepage.Activity.WelcomeGuideActivity;
    import com.example.power.welcomepage.Util.SharedPreferencesUtil;
    
    public class WelcomeActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            /*首先启动该Activity,并判断是否是第一次启动,注意,需要添加默认值,
            * 如果是第一次启动,则先进入功能引导页*/
            boolean isFirstOpen = SharedPreferencesUtil.getBoolean(this, SharedPreferencesUtil.FIRST_OPEN, true);
            if(isFirstOpen){
                Intent intent = new Intent(this, WelcomeGuideActivity.class);
                startActivity(intent);
                /*注意,需要使用finish将该activity进行销毁,否则,在按下手机返回键时,会返回至启动页*/
                finish();
                return;
            }
            /*如果不是第一次启动app,则启动页*/
            setContentView(R.layout.activity_welcome);
    
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    /*2秒后进入主页*/
                    enterHomeActivity();
                }
            },2000);
        }
    
        private void enterHomeActivity(){
            Intent intent = new Intent(this, MainActivity.class);
            startActivity(intent);
            finish();
        }
    }
    

    WelcomeGuideActivity.java

    package com.example.power.welcomepage.Activity;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    
    import com.example.power.welcomepage.Adapter.GuideViewPagerAdapter;
    import com.example.power.welcomepage.R;
    import com.example.power.welcomepage.Util.SharedPreferencesUtil;
    import com.example.power.welcomepage.WelcomeActivity;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by Power on 2018/11/2.
     */
    
    public class WelcomeGuideActivity extends Activity implements View.OnClickListener {
        private ViewPager viewPager;
        private GuideViewPagerAdapter adapter;
        private List<View> views;
        private Button startBtn;
    
        /*引导页图片资源*/
        private static final int[] pics = {  R.layout.guid_view1,
                R.layout.guid_view2, R.layout.guid_view3, R.layout.guid_view4 };
    
        /*底部小点图片*/
        private ImageView[] dots;
    
        /*用于记录当前选中位置*/
        private int currentIndex;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_guide);
    
            views = new ArrayList<View>();
    
            /*初始化引导页视图列表,需要对资源进行处理*/
            for(int i = 0; i < pics.length; i++){
                View view = LayoutInflater.from(this).inflate(pics[i], null);
    
                if(i == pics.length - 1){
                    startBtn = (Button)view.findViewById(R.id.btn_login);
                    /*这里使用setTag方法进行标注。在View中的setTag(Onbect)表示给View
                    添加一个格外的数据,以后可以用getTag()将这个数据取出来。可以用在
                    多个Button添加一个监听器,每个Button都设置不同的setTag。这个监听
                    器就通过getTag来分辨是哪个Button 被按下。*/
                    startBtn.setTag("enter");
                    startBtn.setOnClickListener(this);
                }
                views.add(view);
            }
    
            viewPager = (ViewPager)findViewById(R.id.vp_guide);
            /*初始化adapter*/
            adapter = new GuideViewPagerAdapter(views);
            viewPager.setAdapter(adapter);
            /*需要设置页面改变的监听器,这样我们能把我页面改变时的具体操作细节,所以
            需要创建PageChangeListener,实现OnPageChangeListener接口*/
            viewPager.addOnPageChangeListener(new PageChangeListener());
            initDots();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            /*如果切换到后台,就设置下次不进入功能引导页*/
            SharedPreferencesUtil.setBoolean(WelcomeGuideActivity.this, SharedPreferencesUtil.FIRST_OPEN, false);
            finish();
        }
    
        @Override
        protected void onStop() {
            super.onStop();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
        }
    
        private void initDots(){
            LinearLayout linearLayout = (LinearLayout)findViewById(R.id.ll);
            dots = new ImageView[pics.length];
    
            /*循环取得小点图片*/
            for(int i = 0; i < pics.length; i++){
                /*得到一个LinearLayout下面的每一个子元素*/
                dots[i] = (ImageView)linearLayout.getChildAt(i);
                dots[i].setEnabled(false);//设置成灰色
                dots[i].setOnClickListener(this);
                dots[i].setTag(i);//设置位置tag,方便取出与当前位置对应,原理同上
            }
            currentIndex = 0;
            dots[currentIndex].setEnabled(true); // 设置为白色,即选中状态
        }
    
        /**
         * 设置当前view
         *
         * @param position
         */
        private void  setCurrentView(int position){
            if(position < 0 || position > pics.length){
                return;
            }
            viewPager.setCurrentItem(position);
        }
    
        /**
         * 设置当前指示点
         *
         * @param position
         */
        private void setCurDot(int position) {
            if (position < 0 || position > pics.length || currentIndex == position) {
                return;
            }
            dots[position].setEnabled(true);
            dots[currentIndex].setEnabled(false);
            currentIndex = position;
        }
    
        @Override
        public void onClick(View v) {
            if(v.getTag().equals("enter")){
                enterMainActivity();
                return;
            }
            int position = (Integer) v.getTag();
            setCurrentView(position);
            setCurDot(position);
        }
    
        private void enterMainActivity(){
            Intent intent = new Intent(WelcomeGuideActivity.this, WelcomeActivity.class);
            startActivity(intent);
            SharedPreferencesUtil.setBoolean(WelcomeGuideActivity.this, SharedPreferencesUtil.FIRST_OPEN, false);
            finish();
        }
    
        private class PageChangeListener implements ViewPager.OnPageChangeListener{
            /*当滑动状态改变时调用*/
    
            @Override
            public void onPageScrollStateChanged(int state) {
                /*arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。*/
            }
    
            /*当前页面被滑动时调用*/
    
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // arg0 :当前页面,及你点击滑动的页面
                // arg1:当前页面偏移的百分比
                // arg2:当前页面偏移的像素位置
            }
    
            /*当新的页面被选中时调用*/
            @Override
            public void onPageSelected(int position) {
                setCurDot(position);
            }
        }
    }
    
    SharedPreferencesUtil.java
    package com.example.power.welcomepage.Util;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    
    /**
     * Created by Power on 2018/11/2.
     */
    
    /*我们使用SharedPreferences的数据储存方式进行存取,所以我们创建这个工具类进行封装操作,较为方便可行。
    * 在这里我以我们要使用到的getBoolean和setBoolean进行举例讲解,其余类型原理一致*/
    
    public class SharedPreferencesUtil {
        private static final String FILE_NAME = "welcomePage";
        public static final String FIRST_OPEN = "first_open";
    
        public static Boolean getBoolean(Context context, String strKey,
                                         Boolean strDefault){
            /*使用Context.MODE_PRIVATE模式创建shared preference文件,意味着只用本应用程序
            * 能够使用,还包括MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE 模式的,这两种
            * 模式下,其他任何app均可通过文件名访问该文件。*/
            SharedPreferences sharedPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE
            );
            /*在文件中获取一个Boolean类型值,strDefault是默认值,可以省略,其意义是查找的
            key不存在时函数的返回值。*/
            Boolean result = sharedPreferences.getBoolean(strKey, strDefault);
    
            return result;
        }
    
        public static Boolean getBoolean(Context context, String strKey) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            Boolean result = setPreferences.getBoolean(strKey, false);
            return result;
        }
    
        public static void setBoolean(Context context, String strKey,
                                      Boolean strData){
            SharedPreferences sharedPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE
            );
            /*往shared preference文件中写入值时,我们需要用到SharedPreferences.Editor*/
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putBoolean(strKey, strData);
            editor.commit();
        }
    
        public static String getString(Context context, String strKey) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            String result = setPreferences.getString(strKey, "");
            return result;
        }
    
        public static String getString(Context context, String strKey,
                                       String strDefault) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            String result = setPreferences.getString(strKey, strDefault);
            return result;
        }
    
        public static void setString(Context context, String strKey, String strData) {
            SharedPreferences activityPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = activityPreferences.edit();
            editor.putString(strKey, strData);
            editor.commit();
        }
    
        public static int getInt(Context context, String strKey) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            int result = setPreferences.getInt(strKey, -1);
            return result;
        }
    
        public static int getInt(Context context, String strKey, int strDefault) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            int result = setPreferences.getInt(strKey, strDefault);
            return result;
        }
    
        public static void setInt(Context context, String strKey, int strData) {
            SharedPreferences activityPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = activityPreferences.edit();
            editor.putInt(strKey, strData);
            editor.commit();
        }
    
        public static long getLong(Context context, String strKey) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            long result = setPreferences.getLong(strKey, -1);
            return result;
        }
    
        public static long getLong(Context context, String strKey, long strDefault) {
            SharedPreferences setPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            long result = setPreferences.getLong(strKey, strDefault);
            return result;
        }
    
        public static void setLong(Context context, String strKey, long strData) {
            SharedPreferences activityPreferences = context.getSharedPreferences(
                    FILE_NAME, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = activityPreferences.edit();
            editor.putLong(strKey, strData);
            editor.commit();
        }
    }
    
    GuideViewPagerAdapter.java
    package com.example.power.welcomepage.Adapter;
    
    import android.support.annotation.NonNull;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.view.View;
    import android.view.ViewGroup;
    
    import java.util.List;
    
    /**
     * Created by Power on 2018/11/2.
     */
    
    /*我们需要使用适配器来帮助我们更方便的使用ViewPager*/
    
    public class GuideViewPagerAdapter extends PagerAdapter {
        private List<View> views;
    
        public GuideViewPagerAdapter(List<View> views){
            super();
            this.views = views;
        }
    
        @Override
        public int getCount() {
            if(views != null){
                return views.size();
            }
            return 0;
        }
    
        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            ((ViewPager)container).removeView(views.get(position));
        }
    
        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == ((View)object);
        }
    
        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            ((ViewPager)container).addView(views.get(position), 0);
            return views.get(position);
        }
    }
    

    XML资源文件

    guid_view1.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">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@mipmap/welcomimg3"/>
        <!--我们在使用imageview时一些图片的尺寸大小比例不一样,为了让所有图片都
        能填充整个imageview,就可以使用这个属性,它可以让图片保持原有比例充满imageview,
        并将超出屏幕的部分裁剪掉。-->
    </LinearLayout>

    guid_view2.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">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@mipmap/welcomimg5"/>
    </LinearLayout>

    guid_view3.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">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@mipmap/welcomimg6"/>
    </LinearLayout>

    guid_view4.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!--第四个View布局(也就是放置按钮的那个布局)要使用FrameLayout
        因为需要使用Button在ImageView上方,普通的线性布局做不到,所以需
        要使用帧布局(FrameLayout),即后定义的布局在上方,一层一层叠加-->
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@mipmap/welcomimg11"/>
    
        <!--正规来讲,应该尽量把宽度高度等值放在values的资源文件中,
        这里为了方便,直接写在了布局文件中-->
        <Button
            android:id="@+id/btn_login"
            android:layout_width="160dp"
            android:layout_height="42dp"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="100dp"
            android:background="@drawable/button_shape"
            android:text="立刻体验"
            android:textColor="#ce102c"
            android:textSize="18sp"
            android:visibility="visible"/>
    
    </FrameLayout>

    activity_guide.xml

    <?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="match_parent">
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <android.support.v4.view.ViewPager
                android:id="@+id/vp_guide"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </FrameLayout>
        <LinearLayout
            android:id="@+id/ll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="24.0dip"
            android:orientation="horizontal" >
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:clickable="true"
                android:padding="10.0dip"
                android:src="@drawable/dot_selector" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:clickable="true"
                android:padding="10.0dip"
                android:src="@drawable/dot_selector" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:clickable="true"
                android:padding="10.0dip"
                android:src="@drawable/dot_selector" />
    
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:clickable="true"
                android:padding="10.0dip"
                android:src="@drawable/dot_selector" />
        </LinearLayout>
    
    </RelativeLayout>

    以上就是较为核心的代码,想要了解整个项目的小伙伴,可以下载源码查看哦,里面进行了详细的注解。

    展开全文
  • Flutter实战之闪屏启动页

    千次阅读 2019-07-14 10:33:02
    在APP启动之前,一般都会SplashPage页面,这页面包含闪屏启动页(启动APP的过渡页面)、引导页(APP简介说明)、广告页(点击在浏览器中打开H5页面、或者直接下载APP文件)。 实现思路 APP的第一个页面就是闪屏启动...

    在APP启动之前,一般都会SplashPage页面,这页面包含闪屏启动页(启动APP的过渡页面)、引导页(APP简介说明)、广告页(点击在浏览器中打开H5页面、或者直接下载APP文件)。

    实现思路

    APP的第一个页面就是闪屏启动页面,然后再处理跳转H5广告页面,还是跳转到首页的逻辑。SplashPage分为四层,默认启动图,引导图,广告图,倒计时跳过 使用status来控制页面显示状态,status=0显示启动图,status=1显示广告图和倒计时跳过,status=2显示引导图。

    class MyApp extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
    
        final router = Router();
        Routers.configureRouters(router);
        Application.router = router;
    
        return MaterialApp(
          title: 'Flutter Demo',
          onGenerateRoute: Application.router.generator,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: SplashPage(),
        );
      }
    }
    

    依赖的第三方库

    1. fluro Flutter路由管理
    2. shared_preferences 简单数据的持久化存储
    3. cached_network_image 显示网络图片并保存到cache中
    4. url_launcher 打开URL。包括打电话、发短信、在浏览器中打开地址等URL
    5. flutter_inappbrowser 内联webview或应用程序内浏览器窗口
    6. flukit Flutter 常用库集合

    以上的库都是比较常用的,当然也可以自行选择其他库或者不使用。

    实现步骤

    一、解决Android启动白屏

    在Android原生的mipmap目录下放闪屏背景图,可以根据不同分辨率放入。
    然后修改Android原生的drawable目录下的launch_background.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Modify this file to customize your launch splash screen -->
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@android:color/white" />
    
        <!-- You can insert your own image assets here -->
        <!-- <item>
            <bitmap
                android:gravity="center"
                android:src="@mipmap/launch_image" />
        </item> -->
        <!-- 撑满屏幕、可能会有拉伸 -->
        <item android:drawable="@mipmap/splash_bg"></item>
    </layer-list>
    

    二、构建基础页面

    根据status,使用Stack + Offset来显示不同的页面。使用Stack + Align来绝对定位部分子组件。注意:必须先把图片放到assets/images文件夹下,然后在pubspec.yaml中定义

    // 构建闪屏背景
    Widget _buildSplashBg() {
      return new Image.asset(
        'assets/images/splash_bg.png',
        width: double.infinity,
        height: double.infinity,
        fit: BoxFit.fill,
      );
    }
    
    // 构建广告
    Widget _buildAdWidget() {
      return new InkWell(
          onTap: () {
            print('点击了广告图');
          },
          child: new Container(
            alignment: Alignment.center,
            child: new CachedNetworkImage(
              width: double.infinity,              
              height: double.infinity,
              fit: BoxFit.fill,
              imageUrl: _splashModel.imgUrl,
              placeholder: (context, url) => _buildSplashBg(),
              errorWidget: (context, url, error) => _buildSplashBg(),
            ),
          ),
        ),
      );
    }
    
    // 构建引导页
    _initGuideBanner() {
      setState(() {
        _status = 2;
      });
      for (int i = 0, length = _guideList.length; i < length; i++) {
        if (i == length - 1) {
          _bannerList.add(new Stack(
            children: <Widget>[
              new Image.asset(
                _guideList[i],
                fit: BoxFit.fill,
                width: double.infinity,
                height: double.infinity,
              ),
              new Align(
                alignment: Alignment.bottomCenter,
                child: new Container(
                  margin: EdgeInsets.only(bottom: 160.0),
                  child: new InkWell(
                    onTap: () {
                      _goMain();
                    },
                    child: new CircleAvatar(
                      radius: 48.0,
                      backgroundColor: Colors.indigoAccent,
                      child: new Padding(
                        padding: EdgeInsets.all(2.0),
                        child: new Text(
                          '立即体验',
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.white, fontSize: 16.0),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ));
        } else {
          // print(_guideList[i]);
          _bannerList.add(new Image.asset(
            _guideList[i],
            fit: BoxFit.fill,
            width: double.infinity,
            height: double.infinity,
          ));
        }
      }
    }
    
    // Stack + Offset。Swiper来自于flukit
    @override
    Widget build(BuildContext context) {
      return new Material(
        child: new Stack(
          children: <Widget>[
            new Offstage(
              offstage: !(_status == 0),
              child: _buildSplashBg(),
            ),
            new Offstage(
              offstage: !(_status == 2),
              child: _bannerList.isEmpty
                  ? new Container()
                  : new Swiper(
                      autoStart: false,
                      circular: false,
                      indicator: CircleSwiperIndicator(
                        radius: 4.0,
                        padding: EdgeInsets.only(bottom: 30.0),
                        itemColor: Colors.black26,
                      ),
                      children: _bannerList),
            ),
            _buildAdWidget(),
            new Offstage(
              offstage: !(_status == 1),
              child: new Container(
                alignment: Alignment.bottomRight,
                margin: EdgeInsets.all(20.0),
                child: InkWell(
                  onTap: () {
                    _goMain();
                  },
                  child: new Container(
                      padding: EdgeInsets.all(12.0),
                      child: new Text(
                        '$_count 跳转',
                        style: new TextStyle(fontSize: 14.0, color: Colors.white),
                      ),
                      decoration: new BoxDecoration(
                          color: Color(0x66000000),
                          borderRadius: BorderRadius.all(Radius.circular(4.0)),
                          border: new Border.all(
                              width: 0.33, color: Colors.grey))),
                ),
              ),
            )
          ],
        ),
      );
    

    三、实现闪屏相关逻辑

    倒计时。使用Timer.periodic

    _timer = Timer.periodic(new Duration(seconds: 1), (timer) {
      setState(() {
        if (_count <= 1) {
          _timer.cancel();
          _timer = null;
          _goMain();
        } else {
          _count = _count - 1;
        }
      });
    });
    

    判断是否已经加载过引导图

    SharedPreferences prefs = await SharedPreferences.getInstance();
    bool isGuide = prefs.getBool(Constant.key_guide) ?? true;
    // 是否已经加载过引导图
    if (isGuide) {
      _initGuideBanner();
    } else {
      _initSplash();
    }
    

    完整代码

    splash_page.dart

    import 'package:fluro/fluro.dart';
    import 'package:flutter/material.dart';
    import 'package:music_app/router/routers.dart';
    import 'package:quiver/strings.dart';
    import 'dart:convert';
    import 'dart:async';
    import 'package:shared_preferences/shared_preferences.dart';
    import 'package:cached_network_image/cached_network_image.dart';
    import 'package:flukit/flukit.dart';
    import 'package:url_launcher/url_launcher.dart';
    import 'package:music_app/utils/http_utils.dart';
    import 'package:music_app/common/common.dart';
    import 'package:music_app/models/splash_model.dart';
    import 'package:music_app/router/application.dart';
    
    class SplashPage extends StatefulWidget {
      @override
      _SplashPageState createState() => _SplashPageState();
    }
    
    class _SplashPageState extends State<SplashPage> {
    
      List<String> _guideList = [
        'assets/images/guide1.png',
        'assets/images/guide2.png',
        'assets/images/guide3.png',
        'assets/images/guide4.png'
      ];
    
      List<Widget> _bannerList = new List();
    
      Timer _timer;
      int _status = 0; // 0-启动图,1-广告图和倒计时跳过,2-引导图。
      int _count = 3; // 倒计时秒数
    
      SplashModel _splashModel;
    
      @override
      void initState() {
        super.initState();
        _initAsync();
      }
    
      void _initAsync() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        // 获取上次存储的闪屏页面
        String jsonStr = prefs.getString(Constant.key_splash_model);
        if (isNotEmpty(jsonStr)) {
          Map<String, dynamic> splash = json.decode(jsonStr);
          _splashModel = SplashModel.fromJson(splash);
        }
    
        HttpUtils httpUtils = new HttpUtils();
        // 获取闪屏的广告数据
        httpUtils.getSplash().then((model) {
          if (isNotEmpty(model.imgUrl)) {
            if (_splashModel == null || (_splashModel.imgUrl != model.imgUrl)) {
              prefs.setString(Constant.key_splash_model, model.toString());
              setState(() {
                _splashModel = model;
              });
            }
          } else {
            prefs.setString(Constant.key_splash_model, null);
          }
        });
    
        bool isGuide = prefs.getBool(Constant.key_guide) ?? true;
        // 是否已经加载过引导图
        if (isGuide) {
          _initGuideBanner();
        } else {
          _initSplash();
        }
      }
    
      _initGuideBanner() {
        setState(() {
          _status = 2;
        });
        for (int i = 0, length = _guideList.length; i < length; i++) {
          if (i == length - 1) {
            _bannerList.add(new Stack(
              children: <Widget>[
                new Image.asset(
                  _guideList[i],
                  fit: BoxFit.fill,
                  width: double.infinity,
                  height: double.infinity,
                ),
                new Align(
                  alignment: Alignment.bottomCenter,
                  child: new Container(
                    margin: EdgeInsets.only(bottom: 160.0),
                    child: new InkWell(
                      onTap: () {
                        _goMain();
                      },
                      child: new CircleAvatar(
                        radius: 48.0,
                        backgroundColor: Colors.indigoAccent,
                        child: new Padding(
                          padding: EdgeInsets.all(2.0),
                          child: new Text(
                            '立即体验',
                            textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white, fontSize: 16.0),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ));
          } else {
            // print(_guideList[i]);
            _bannerList.add(new Image.asset(
              _guideList[i],
              fit: BoxFit.fill,
              width: double.infinity,
              height: double.infinity,
            ));
          }
        }
      }
    
      _initSplash() {
        if (_splashModel == null) {
          _goMain();
          return;
        }
        setState(() {
          _status = 1;
        });
    
        // 倒计时
        _timer = Timer.periodic(new Duration(seconds: 1), (timer) {
          setState(() {
            if (_count <= 1) {
              _timer.cancel();
              _timer = null;
              _goMain();
            } else {
              _count = _count - 1;
            }
          });
        });
      }
    
      // 跳转主页
      void _goMain() {
        Application.router.navigateTo(context, Routers.mainPage, replace: true, transition: TransitionType.fadeIn);
      }
    
      // 构建闪屏背景
      Widget _buildSplashBg() {
        return new Image.asset(
          'assets/images/splash_bg.png',
          width: double.infinity,
          fit: BoxFit.fill,
          height: double.infinity,
        );
      }
    
      // 构建广告
      Widget _buildAdWidget() {
        if (_splashModel == null) {
          return new Container(
            height: 0.0,
          );
        }
        return new Offstage(
          offstage: !(_status == 1),
          child: new InkWell(
            onTap: () async {
              String url = _splashModel.url;
              if (isEmpty(url)) return;
              _goMain();
              if (url.endsWith(".apk")) {
                // 打开浏览器下载APK
                if (await canLaunch(url)) {
                  await launch(url, forceSafariVC: false, forceWebView: false);
                }
              } else {
                // 在浏览器中打开url
                Application.router.navigateTo(context, Routers.adPage + '?title=${Uri.encodeComponent(_splashModel.title)}&url=${Uri.encodeComponent(_splashModel.url)}', transition: TransitionType.fadeIn);
              }
            },
            child: new Container(
              alignment: Alignment.center,
              child: new CachedNetworkImage(
                width: double.infinity,              
                height: double.infinity,
                fit: BoxFit.fill,
                imageUrl: _splashModel.imgUrl,
                placeholder: (context, url) => _buildSplashBg(),
                errorWidget: (context, url, error) => _buildSplashBg(),
              ),
            ),
          ),
        );
      }
    
      @override
      void dispose() {
        _timer?.cancel();
        _timer = null;
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Material(
          child: new Stack(
            children: <Widget>[
              new Offstage(
                offstage: !(_status == 0),
                child: _buildSplashBg(),
              ),
              new Offstage(
                offstage: !(_status == 2),
                child: _bannerList.isEmpty
                    ? new Container()
                    : new Swiper(
                        autoStart: false,
                        circular: false,
                        indicator: CircleSwiperIndicator(
                          radius: 4.0,
                          padding: EdgeInsets.only(bottom: 30.0),
                          itemColor: Colors.black26,
                        ),
                        children: _bannerList),
              ),
              _buildAdWidget(),
              new Offstage(
                offstage: !(_status == 1),
                child: new Container(
                  alignment: Alignment.bottomRight,
                  margin: EdgeInsets.all(20.0),
                  child: InkWell(
                    onTap: () {
                      _goMain();
                    },
                    child: new Container(
                        padding: EdgeInsets.all(12.0),
                        child: new Text(
                          '$_count 跳转',
                          style: new TextStyle(fontSize: 14.0, color: Colors.white),
                        ),
                        decoration: new BoxDecoration(
                            color: Color(0x66000000),
                            borderRadius: BorderRadius.all(Radius.circular(4.0)),
                            border: new Border.all(
                                width: 0.33, color: Colors.grey))),
                  ),
                ),
              )
            ],
          ),
        );
      }
    }
    

    splash_model.dart

    class SplashModel {
      String title;
      String content;
      String url;
      String imgUrl;
    
      SplashModel({this.title, this.content, this.url, this.imgUrl});
    
      SplashModel.fromJson(Map<String, dynamic> json)
          : title = json['title'],
            content = json['content'],
            url = json['url'],
            imgUrl = json['imgUrl'];
    
      Map<String, dynamic> toJson() => {
            'title': title,
            'content': content,
            'url': url,
            'imgUrl': imgUrl,
          };
    
      @override
      String toString() {
        StringBuffer sb = new StringBuffer('{');
        sb.write("\"title\":\"$title\"");
        sb.write(",\"content\":\"$content\"");
        sb.write(",\"url\":\"$url\"");
        sb.write(",\"imgUrl\":\"$imgUrl\"");
        sb.write('}');
        return sb.toString();
      }
    }
    

    本文参考wanandroid,感谢鸿洋大神

    展开全文
  • Android中启动页的实现

    千次阅读 2018-06-13 11:59:33
    我的启动页展示 背景 只要是一个app,每次打开的时候会显示启动页面,然后再进入主界面。下面看几个app的启动页展示: 我的思路 启动页面肯定是要打开就显示的,然后用一个Activity展示。界面...
  • Flutter 修改应用名称、图标、启动页

    千次阅读 2019-08-09 15:19:01
    虽然flutter可以同时运行在android和ios设备上,但是修改名称、logo、启动页还是需要分开配置的。 修改应用名称 android 在项目下找到 android 目录,依次app》src》main》AndroidManifest.xml, 打开 ...
  • uniapp启动页面

    千次阅读 2020-08-06 15:08:39
    1.找一张需要启动页面的图片放在static 文件夹下 2.index页面就是启动页面,并且取消默认标题 "pages": [{ "path": "pages/index/index", "style": { "app-plus":{ "titleNView":false } } },{ "path":...
  • Android配置启动页

    千次阅读 2019-01-23 20:07:40
    Android中几乎所有app都有启动页这一基本功能,但是用途都不相同。 有的app的启动页用于加载广告,有的启动页用于加载后台,一旦后台数据加载好了才把启动页去了,不过想来很多app是两者兼顾的。 自己写的app是很少...
  • Android启动页的简单实现

    千次阅读 2018-12-05 20:36:00
    之前做的几个app由于没考虑加启动页(毕竟是打比赛用的,没做细节),都是一点开出现一个空白页,然后过几秒才加载出视图,体验是真的不行。直到现在真的要做一个属于自己的项目了,才去关注了下这个问题。好吧,...
  • Android 启动页适配&启动优化

    万次阅读 2019-01-23 20:30:33
    首当其冲的是就是启动页的适配了,尽管只有一张单图,为了保持他不变形绞尽脑汁想了无数办法,最终找到一个简单的方案。先说下当前的分辨率。 主流屏 16:9 1280*720 1.777 1920*1080 1.777 2560*1440 1.777 非主流...
  • flutter 启动页设置

    千次阅读 2020-04-19 21:13:21
    1、在main.dart的MaterialApp内,将home对应的组件内容设置成,启动页所在组件 2、在启动页所在路由设置启动图片等 3、在initState()生命周期函数中设置延迟函数,n秒后跳转到其他路由页面即可 代码示例: main.dart: ...
  • Android 启动页面与广告页面的实现

    万次阅读 多人点赞 2017-03-26 16:46:27
    在我们APP的开发过程中,启动页面是绕不开的,广告页面说不定,但是不得不说,这两个界面都是经常要用到的。接下来我记录一下我的实现过程。项目架构为MVP。  那么先看看我们的需求和流程:(当然这也是可以根据...
  • APP设计之启动页和广告页

    千次阅读 2018-08-30 15:01:06
    苹果官方对于iOS启动页的设计说明:为了增强应用程序启动时的用户体验,您应该提供一个启动图像。启动图像与应用程序的首屏幕看起来非常相似。当用户在主屏幕上点击您的应用程序图标时,iPhone OS会立即显示这个启动...
  • WPF 启动页面

    千次阅读 2017-06-26 19:26:01
    如果我写的有误,请及时与我联系,我立即改之...wpf软件启动时,加载启动页面。软件初始化完成之后关闭页面。 App.xaml.cs代码 (实现加载页面功能) public partial class App : Application { protected ov
  • Cocos Creator 去除或更改默认启动页(Web端)

    万次阅读 热门讨论 2019-03-11 17:56:22
    Cocos Creator 的默认启动页可以直接去除,也可以更改图标,删除进度条,或者自己添加一些加载动效。 本篇文章介绍的是构建为 web 形式,构建Android或者iOS不在此介绍...
  • 启动页设置 uniapp自带的启动页是一个白底的页面,上面有个uni的logo,然后周围有个圆圈的进度条,这个是启动页。 uniapp中可以自定义启动页,注意两点: 不要勾选“启动界面显示等待雪花” Android启动界面设置中...
  • app启动优化和启动页适配方案

    千次阅读 2020-03-10 19:27:16
    写在前面,关于启动页适配方案,百度了一下网上的解决办法,发现很多人使用xml布局文件和启动大图的方式进行启动页适配, 还有进行了宽高比进行多图适配,我反复实验后,发现这两种方式并不是很好,大部分主流机型都...
  • Chrome启动页设置无效完美解决

    千次阅读 2019-10-09 01:04:20
    Chrome明明设置了百度为启动页,打开仍然是Google
  • Xcode 12设置启动页面

    千次阅读 2020-11-06 16:38:19
    图片一定要PNG格式,不要直接改后缀名!!!!!!!!
  • 启动页面的制作。 解决设置.9图片为windowBackground之后屏幕严重变形。
  • Android 启动页优化及过渡动画

    千次阅读 2018-06-27 14:18:50
    一、APP的启动方式:一般来说,APP的启动方式主要分为两种:冷启动和热启动。冷启动启动应用时,后台没有该应用的进程,系统会重新创建一个新的进程分配给该应用,即冷启动;热启动启动应用时,后台已有该应用的...
  • 1、产生原因 关于点击app图标出现白屏和黑屏的产生原因,首先要说的就是app的启动模式:冷启动(cold start),暖启动(warm start),热启动(lukewarm start)。冷启动:是指进程从无到有的过程。因为要进行页面初始化...
  • android studio 启动页的视频效果

    千次阅读 2018-10-22 20:37:57
    很是羡慕,别人app 的启动页的视频效果。所以自己也做了一个。 首先要提醒大家的是:要做启动页,一定要在项目创建最初的那个activity里做,不然的话,改起来非常麻烦,并且,之后运行起来会黑屏。 那下面一步步的来...
  • 搞了一个DEMO,不知道启动路径是啥 ...默认启动页为:localhost:8080但是我们每次都手动输入地址非常的麻烦,怎么配置自动起来呢? 1.首先在Springboot项目中添加测试类ControllerTest ,测试类ControllerTest ...
  • mui 启动页和引导页

    千次阅读 2017-09-30 14:02:06
    一、启动页和引导页的概念 “启动页”(splash):app的启动界面,每次启动都会看到的(每次打开QQ都会看到一只企鹅)。 “引导页”(guide):guide是否展示是可控的,通常首次启动时显示,从第二次启动开始,引导...
  • 安卓应用图标和开机启动页大小

    千次阅读 2019-10-17 09:17:03
    正文 icon图标尺寸: drawable-ldpi-icon 36*36 drawable-mdpi-icon 48*48 drawable-hdpi-icon 72*72 drawable-xhdpi-icon 96*96 drawable-xxhdpi-icon 144*144 ...启动页: 横屏 宽×高 drawab...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,116,580
精华内容 446,632
关键字:

启动页