无法 运行 SplashScreen 和 OnBoarding 屏幕在一起
Couldn't run SplashScreen and OnBoarding screen together
当我 运行 我的应用程序时,我看不到任何 Splash Screen.I 从视频中执行此操作,并且我已将我的 AndroidManifest 设置设置为视频中的设置。我将我的 SplashScreen 放在 Manifest 文件中 MainActivity 的顶部并将其设置为正常(就像我创建我的启动画面时一样activity)但它仍然不起作用。
我的AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.labawsrh.aws.introscreen">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SplashScreen"></activity>
<activity android:name=".finalActivity" />
<activity android:name=".interests" />
<activity android:name=".IntroActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
</manifest>
SplashScreen.java:
public class SplashScreen extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, 3000);
}
}
activity_splash_screen.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"
android:background="@drawable/splash_gradient"
>
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:id="@+id/logo"
android:layout_centerInParent="true"
android:src="@drawable/whitegift"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:textColor="#ffffff"
android:layout_alignParentBottom="true"
android:text="Gift Finder"
android:textSize="60dp"
android:fontFamily="@font/intoscript"
android:gravity="center_horizontal"
android:paddingBottom="130dp"/>
</RelativeLayout>
IntroActivty.java(OnBoarding 屏幕代码):
public class IntroActivity extends AppCompatActivity {
private ViewPager screenPager;
IntroViewPagerAdapter introViewPagerAdapter ;
TabLayout tabIndicator;
Button btnNext;
int position = 0 ;
Button btnGetStarted;
Animation btnAnim ;
TextView tvSkip;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// make the activity on full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// when this activity is about to be launch we need to check if its openened before or not
if (restorePrefData()) {
Intent mainActivity = new Intent(getApplicationContext(),MainActivity.class );
startActivity(mainActivity);
finish();
}
setContentView(R.layout.activity_intro);
// hide the action bar
//getSupportActionBar().hide();
// ini views
btnNext = findViewById(R.id.btn_next);
btnGetStarted = findViewById(R.id.btn_get_started);
tabIndicator = findViewById(R.id.tab_indicator);
btnAnim = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.button_animation);
tvSkip = findViewById(R.id.tv_skip);
// fill list screen
final List<ScreenItem> mList = new ArrayList<>();
mList.add(new ScreenItem("Best Advice!","GiftFinder is an app that gives you the best gift advices.",R.drawable.advice));
mList.add(new ScreenItem("How It Works?","Our AI code just needs couple info to find the best gift.",R.drawable.aicode));
mList.add(new ScreenItem("Then..","Let the AI find the best gift for you!",R.drawable.ai));
// setup viewpager
screenPager =findViewById(R.id.screen_viewpager);
introViewPagerAdapter = new IntroViewPagerAdapter(this,mList);
screenPager.setAdapter(introViewPagerAdapter);
// setup tablayout with viewpager
tabIndicator.setupWithViewPager(screenPager);
// next button click Listner
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
position = screenPager.getCurrentItem();
if (position < mList.size()) {
position++;
screenPager.setCurrentItem(position);
}
if (position == mList.size()-1) { // when we rech to the last screen
// TODO : show the GETSTARTED Button and hide the indicator and the next button
loaddLastScreen();
}
}
});
// tablayout add change listener
tabIndicator.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == mList.size()-1) {
loaddLastScreen();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
// Get Started button click listener
btnGetStarted.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//open main activity
Intent mainActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(mainActivity);
// also we need to save a boolean value to storage so next time when the user run the app
// we could know that he is already checked the intro screen activity
// i'm going to use shared preferences to that process
savePrefsData();
finish();
}
});
// skip button click listener
tvSkip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
screenPager.setCurrentItem(mList.size());
}
});
}
private boolean restorePrefData() {
SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
Boolean isIntroActivityOpnendBefore = pref.getBoolean("isIntroOpnend",false);
return isIntroActivityOpnendBefore;
}
private void savePrefsData() {
SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("isIntroOpnend",true);
editor.commit();
}
// show the GETSTARTED Button and hide the indicator and the next button
private void loaddLastScreen() {
btnNext.setVisibility(View.INVISIBLE);
btnGetStarted.setVisibility(View.VISIBLE);
tvSkip.setVisibility(View.INVISIBLE);
tabIndicator.setVisibility(View.INVISIBLE);
// TODO : ADD an animation the getstarted button
// setup animation
btnGetStarted.setAnimation(btnAnim);
}
}
SplashScreen
必须是您的启动器 activity。您的启动器 IntroActivity
activity。更新了您的 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.labawsrh.aws.introscreen">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"/>
<activity android:name=".finalActivity" />
<activity android:name=".interests" />
// Made SplashScreen Launcher Activity
<activity android:name=".SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".IntroActivity" />
</application>
</manifest>
我是 android 的新手,我的解决方案可能不像您通常认为的那样是正确的解决方案。首先抱歉我的英语不好。在我看来,启动画面是介绍您和您的应用程序的唯一且优雅的方式。它必须快速且持续时间短。我在互联网上找到了很多解决方案,但所有页面和所有片段的 90% 都是相同的(似乎很多人都在同一个第一个解决方案上进行了剪切/粘贴)。所以我决定实施我自己的解决方案。对不起我的原始代码。我已经实现了所有功能 Activity:在您的应用中,您只需插入以下修改:
-) 第一步:activity_main.xml(主布局),全部包含在一个FrameLayout中:
<androidx.drawerlayout.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:visibility="invisible"
tools:openDrawer="start">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id = "@+id/frameContainer">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
目标 FrameLayout (@id/frameContainer) 是闪屏容器。
-) 第二步:在drawable目录下插入一张位图,应该是启动画面背景,在我的例子中我还准备了一个矩形space,插入我的动态字符串(例如“touch开始”和“版本号 000.00.00”)。我的位图id是“@drawable/applogothumb”,同样在字符串文件中,我插入了一个字符串“@string/toccasplash”。在位图上,我还为字符串取了矩形 space 的像素坐标。
-) 第三步:在主应用中声明和使用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Util.hideStatusBar(this);
setContentView(R.layout.activity_main);
//Qui lancio la thumb, il controllo passato [ frameContainer ] deve essere
//un FrameLayout in modo che la thumb stia sopra tutto il resto
CMainSplashBox thumb = new CMainSplashBox(this,
R.id.frameContainer, //FrameLayout ID Step 1
R.drawable.applogothumb, //Bitmap ID Step 2
R.string.toccasplash, //Stringa ID
CVersions.APP_VERSION, //Version number (String)
//pixel coordinate of the rectangular space for the strings
new Rect(TWRITE_ORG_X,TWRITE_ORG_Y,TWRITE_END_X,TWRITE_END_Y),
//Time duration in seconds
10);
mCsd = new CSerializeData(this);
mCsd.loadConfiguration();
....
....
如您所见,所有内容都在 CMainSplashBox class 中进行管理。我不需要其他任何东西。同时显示启动画面,应用程序可以完成构建代码并继续执行。
一切都在 class 中,管理点击关闭它和计时器计时。
class 在这里。在你看到 class 之前,请记住这是我的第一个实验,里面的代码是为我自己的范围编写的,但我认为它有工作的材料,或者有人可以建议我如何改进这个想法...
public class CMainSplashBox extends LinearLayoutCompat {
private Timer statusCommandsTimer = null;
private int mDurata = 5000; //seconds/1000
private int mPeriodo = 1000;
private FrameLayout padre;
private CMainSplashBox figlio;
private Context mCtx;
private Bitmap mSplash;
private int mIdSplash = -1;
private String mText;
private String mVer;
private float DIM_X = 963;
private float DIM_Y = 700;
private float ORG_X = 95;
private float ORG_Y = 475;
private float END_X = 877;
private float END_Y = 568;
private int mFontMis = 70;
private double mTotTxSpace = 50;
private double mLfontD = 15;
private double mBfontD = 28;
/*
@context = appContext
@id = FrameLayout ID
@idd = Bitmap ID
@idText = String ID
@ver = Version number string
@th = Pixel coordinate
@durata = wait in second
*/
public CMainSplashBox(Context context,int id,int idd,int idText ,String ver, Rect
th,int durata){
super(context);
mCtx = context;
mDurata = durata * 1000;
mIdSplash = idd;
ORG_X = th.left;
ORG_Y = th.top;
END_X = th.right;
END_Y = th.bottom;
mVer = "Version.: "+ver;
mText = ((AppCompatActivity)context).getText(idText).toString();
Point pt = Util.getOriginalBitmapDims(context.getResources(),idd);
DIM_X = pt.x;
DIM_Y = pt.y;
FrameLayout.LayoutParams vgl = new
FrameLayout.LayoutParams(MATCH_PARENT,MATCH_PARENT);
vgl.gravity= Gravity.CENTER;
figlio = this;
padre = ((AppCompatActivity)context).findViewById(id);
padre.addView(this);
setBackgroundColor(0xCC000000);
setLayoutParams(vgl);
setPadding(5,5,5,5);
setEnabled(true);
statusCommandsTimer = startTimer(statusCommandsTimer,0, mPeriodo);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//here I can close the Splash if the screen have been touched
mDurata = 0;
}
});
}
//Draw the splash screen and make some calculations on the bitmaps
//Util is my library with some common routines
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSplash == null){
mSplash = Util.getBitmap(mCtx,mIdSplash,canvas.getWidth(),canvas.getHeight());
}
if (mSplash != null){
int dmx = mSplash.getWidth();
int dmy = mSplash.getHeight();
float dx = (canvas.getWidth()-dmx)/2;
float dy = (canvas.getHeight()-dmy)/2;
canvas.drawBitmap(mSplash,dx,dy,null);
int orgx = (int)(((ORG_X * dmx)/DIM_X)+dx);
int orgy = (int)(((ORG_Y * dmy)/DIM_Y)+dy);
int endx = (int)(((END_X * dmx)/DIM_X)+dx);
int endy = (int)(((END_Y * dmy)/DIM_Y)+dy);
Paint p = new Paint();
Rect bounds = new Rect();
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
p.setTypeface(Typeface.DEFAULT_BOLD);
int thumbw = (endx-orgx)-10;
bounds.offset(0, -bounds.top);
double spt = (bounds.height() * mTotTxSpace)/mBfontD;
if ((endy-orgy) < (int)spt){
mFontMis =(int)(((endy-orgy) * mFontMis) / spt);
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
bounds.offset(0, -bounds.top);
spt = (bounds.height() * mTotTxSpace)/mBfontD;
}
if (thumbw < bounds.width()){
mFontMis = (thumbw*mFontMis)/bounds.width();
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
bounds.offset(0, -bounds.top);
}
dmx = ((endx-orgx)-bounds.width())/2;
dmy = (endy-orgy)-bounds.height();
spt = bounds.height();
p.setColor(0xff000000);
canvas.drawText(mText, orgx+dmx, endy-dmy, p);
int fm = (int)((mFontMis * mLfontD) / mBfontD);
p.setTextSize(fm);
p.getTextBounds(mText, 0, mVer.length(), bounds);
bounds.offset(0, -bounds.top);
dmx = ((endx-orgx)-bounds.width())/2;
int spy = (int)(mTotTxSpace -(mLfontD+mBfontD));
dmy = (int)((endy-orgy)-(bounds.height()+(((endy-orgy) *
spy)/mTotTxSpace)));
canvas.drawText(mVer, orgx+dmx, (endy-dmy)+(float)spt, p);
}
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mSplash != null) mSplash.recycle();
mSplash = null;
//Ridisegna
invalidate();
}
// // // // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // // // //
// Wait Timer
private Timer startTimer(Timer tt, int delay, int period) {
Timer itt = tt;
if (itt == null) {
itt = new Timer();
itt.schedule(new TimerTask() {
@Override
public void run() {
TimeCounter();
}
}, delay, period);
}
return itt;
}
private void stopTimers(Timer tt) {
if (tt != null) {
tt.cancel();
tt.purge();
}
}
//Calculate the residual time
private void TimeCounter(){
mDurata -= mPeriodo;
if (mDurata <= 0 && mCtx instanceof AppCompatActivity){
stopTimers(statusCommandsTimer);
((AppCompatActivity)mCtx).runOnUiThread(Timer_Tick);
}
}
//This function is necessary because I have to remove the splash screen and
//Remove the bitmap from the timer thread
private Runnable Timer_Tick = new Runnable() {
public void run() {
setEnabled(false);
setVisibility(INVISIBLE);
//for safety only as you are doing onClick
if(null!=padre && figlio != null)
padre.removeView(figlio);
if (mSplash != null) mSplash.recycle();
}
};
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
}
就是这样。欢迎任何建议或改进。
当我 运行 我的应用程序时,我看不到任何 Splash Screen.I 从视频中执行此操作,并且我已将我的 AndroidManifest 设置设置为视频中的设置。我将我的 SplashScreen 放在 Manifest 文件中 MainActivity 的顶部并将其设置为正常(就像我创建我的启动画面时一样activity)但它仍然不起作用。
我的AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.labawsrh.aws.introscreen">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".SplashScreen"></activity>
<activity android:name=".finalActivity" />
<activity android:name=".interests" />
<activity android:name=".IntroActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity" />
</application>
</manifest>
SplashScreen.java:
public class SplashScreen extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, 3000);
}
}
activity_splash_screen.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"
android:background="@drawable/splash_gradient"
>
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:id="@+id/logo"
android:layout_centerInParent="true"
android:src="@drawable/whitegift"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:textColor="#ffffff"
android:layout_alignParentBottom="true"
android:text="Gift Finder"
android:textSize="60dp"
android:fontFamily="@font/intoscript"
android:gravity="center_horizontal"
android:paddingBottom="130dp"/>
</RelativeLayout>
IntroActivty.java(OnBoarding 屏幕代码):
public class IntroActivity extends AppCompatActivity {
private ViewPager screenPager;
IntroViewPagerAdapter introViewPagerAdapter ;
TabLayout tabIndicator;
Button btnNext;
int position = 0 ;
Button btnGetStarted;
Animation btnAnim ;
TextView tvSkip;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// make the activity on full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// when this activity is about to be launch we need to check if its openened before or not
if (restorePrefData()) {
Intent mainActivity = new Intent(getApplicationContext(),MainActivity.class );
startActivity(mainActivity);
finish();
}
setContentView(R.layout.activity_intro);
// hide the action bar
//getSupportActionBar().hide();
// ini views
btnNext = findViewById(R.id.btn_next);
btnGetStarted = findViewById(R.id.btn_get_started);
tabIndicator = findViewById(R.id.tab_indicator);
btnAnim = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.button_animation);
tvSkip = findViewById(R.id.tv_skip);
// fill list screen
final List<ScreenItem> mList = new ArrayList<>();
mList.add(new ScreenItem("Best Advice!","GiftFinder is an app that gives you the best gift advices.",R.drawable.advice));
mList.add(new ScreenItem("How It Works?","Our AI code just needs couple info to find the best gift.",R.drawable.aicode));
mList.add(new ScreenItem("Then..","Let the AI find the best gift for you!",R.drawable.ai));
// setup viewpager
screenPager =findViewById(R.id.screen_viewpager);
introViewPagerAdapter = new IntroViewPagerAdapter(this,mList);
screenPager.setAdapter(introViewPagerAdapter);
// setup tablayout with viewpager
tabIndicator.setupWithViewPager(screenPager);
// next button click Listner
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
position = screenPager.getCurrentItem();
if (position < mList.size()) {
position++;
screenPager.setCurrentItem(position);
}
if (position == mList.size()-1) { // when we rech to the last screen
// TODO : show the GETSTARTED Button and hide the indicator and the next button
loaddLastScreen();
}
}
});
// tablayout add change listener
tabIndicator.addOnTabSelectedListener(new TabLayout.BaseOnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (tab.getPosition() == mList.size()-1) {
loaddLastScreen();
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
// Get Started button click listener
btnGetStarted.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//open main activity
Intent mainActivity = new Intent(getApplicationContext(), MainActivity.class);
startActivity(mainActivity);
// also we need to save a boolean value to storage so next time when the user run the app
// we could know that he is already checked the intro screen activity
// i'm going to use shared preferences to that process
savePrefsData();
finish();
}
});
// skip button click listener
tvSkip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
screenPager.setCurrentItem(mList.size());
}
});
}
private boolean restorePrefData() {
SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
Boolean isIntroActivityOpnendBefore = pref.getBoolean("isIntroOpnend",false);
return isIntroActivityOpnendBefore;
}
private void savePrefsData() {
SharedPreferences pref = getApplicationContext().getSharedPreferences("myPrefs",MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("isIntroOpnend",true);
editor.commit();
}
// show the GETSTARTED Button and hide the indicator and the next button
private void loaddLastScreen() {
btnNext.setVisibility(View.INVISIBLE);
btnGetStarted.setVisibility(View.VISIBLE);
tvSkip.setVisibility(View.INVISIBLE);
tabIndicator.setVisibility(View.INVISIBLE);
// TODO : ADD an animation the getstarted button
// setup animation
btnGetStarted.setAnimation(btnAnim);
}
}
SplashScreen
必须是您的启动器 activity。您的启动器 IntroActivity
activity。更新了您的 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.labawsrh.aws.introscreen">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"/>
<activity android:name=".finalActivity" />
<activity android:name=".interests" />
// Made SplashScreen Launcher Activity
<activity android:name=".SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".IntroActivity" />
</application>
</manifest>
我是 android 的新手,我的解决方案可能不像您通常认为的那样是正确的解决方案。首先抱歉我的英语不好。在我看来,启动画面是介绍您和您的应用程序的唯一且优雅的方式。它必须快速且持续时间短。我在互联网上找到了很多解决方案,但所有页面和所有片段的 90% 都是相同的(似乎很多人都在同一个第一个解决方案上进行了剪切/粘贴)。所以我决定实施我自己的解决方案。对不起我的原始代码。我已经实现了所有功能 Activity:在您的应用中,您只需插入以下修改:
-) 第一步:activity_main.xml(主布局),全部包含在一个FrameLayout中:
<androidx.drawerlayout.widget.DrawerLayout
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:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:visibility="invisible"
tools:openDrawer="start">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id = "@+id/frameContainer">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
目标 FrameLayout (@id/frameContainer) 是闪屏容器。
-) 第二步:在drawable目录下插入一张位图,应该是启动画面背景,在我的例子中我还准备了一个矩形space,插入我的动态字符串(例如“touch开始”和“版本号 000.00.00”)。我的位图id是“@drawable/applogothumb”,同样在字符串文件中,我插入了一个字符串“@string/toccasplash”。在位图上,我还为字符串取了矩形 space 的像素坐标。
-) 第三步:在主应用中声明和使用:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Util.hideStatusBar(this);
setContentView(R.layout.activity_main);
//Qui lancio la thumb, il controllo passato [ frameContainer ] deve essere
//un FrameLayout in modo che la thumb stia sopra tutto il resto
CMainSplashBox thumb = new CMainSplashBox(this,
R.id.frameContainer, //FrameLayout ID Step 1
R.drawable.applogothumb, //Bitmap ID Step 2
R.string.toccasplash, //Stringa ID
CVersions.APP_VERSION, //Version number (String)
//pixel coordinate of the rectangular space for the strings
new Rect(TWRITE_ORG_X,TWRITE_ORG_Y,TWRITE_END_X,TWRITE_END_Y),
//Time duration in seconds
10);
mCsd = new CSerializeData(this);
mCsd.loadConfiguration();
....
....
如您所见,所有内容都在 CMainSplashBox class 中进行管理。我不需要其他任何东西。同时显示启动画面,应用程序可以完成构建代码并继续执行。 一切都在 class 中,管理点击关闭它和计时器计时。 class 在这里。在你看到 class 之前,请记住这是我的第一个实验,里面的代码是为我自己的范围编写的,但我认为它有工作的材料,或者有人可以建议我如何改进这个想法...
public class CMainSplashBox extends LinearLayoutCompat {
private Timer statusCommandsTimer = null;
private int mDurata = 5000; //seconds/1000
private int mPeriodo = 1000;
private FrameLayout padre;
private CMainSplashBox figlio;
private Context mCtx;
private Bitmap mSplash;
private int mIdSplash = -1;
private String mText;
private String mVer;
private float DIM_X = 963;
private float DIM_Y = 700;
private float ORG_X = 95;
private float ORG_Y = 475;
private float END_X = 877;
private float END_Y = 568;
private int mFontMis = 70;
private double mTotTxSpace = 50;
private double mLfontD = 15;
private double mBfontD = 28;
/*
@context = appContext
@id = FrameLayout ID
@idd = Bitmap ID
@idText = String ID
@ver = Version number string
@th = Pixel coordinate
@durata = wait in second
*/
public CMainSplashBox(Context context,int id,int idd,int idText ,String ver, Rect
th,int durata){
super(context);
mCtx = context;
mDurata = durata * 1000;
mIdSplash = idd;
ORG_X = th.left;
ORG_Y = th.top;
END_X = th.right;
END_Y = th.bottom;
mVer = "Version.: "+ver;
mText = ((AppCompatActivity)context).getText(idText).toString();
Point pt = Util.getOriginalBitmapDims(context.getResources(),idd);
DIM_X = pt.x;
DIM_Y = pt.y;
FrameLayout.LayoutParams vgl = new
FrameLayout.LayoutParams(MATCH_PARENT,MATCH_PARENT);
vgl.gravity= Gravity.CENTER;
figlio = this;
padre = ((AppCompatActivity)context).findViewById(id);
padre.addView(this);
setBackgroundColor(0xCC000000);
setLayoutParams(vgl);
setPadding(5,5,5,5);
setEnabled(true);
statusCommandsTimer = startTimer(statusCommandsTimer,0, mPeriodo);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//here I can close the Splash if the screen have been touched
mDurata = 0;
}
});
}
//Draw the splash screen and make some calculations on the bitmaps
//Util is my library with some common routines
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mSplash == null){
mSplash = Util.getBitmap(mCtx,mIdSplash,canvas.getWidth(),canvas.getHeight());
}
if (mSplash != null){
int dmx = mSplash.getWidth();
int dmy = mSplash.getHeight();
float dx = (canvas.getWidth()-dmx)/2;
float dy = (canvas.getHeight()-dmy)/2;
canvas.drawBitmap(mSplash,dx,dy,null);
int orgx = (int)(((ORG_X * dmx)/DIM_X)+dx);
int orgy = (int)(((ORG_Y * dmy)/DIM_Y)+dy);
int endx = (int)(((END_X * dmx)/DIM_X)+dx);
int endy = (int)(((END_Y * dmy)/DIM_Y)+dy);
Paint p = new Paint();
Rect bounds = new Rect();
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
p.setTypeface(Typeface.DEFAULT_BOLD);
int thumbw = (endx-orgx)-10;
bounds.offset(0, -bounds.top);
double spt = (bounds.height() * mTotTxSpace)/mBfontD;
if ((endy-orgy) < (int)spt){
mFontMis =(int)(((endy-orgy) * mFontMis) / spt);
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
bounds.offset(0, -bounds.top);
spt = (bounds.height() * mTotTxSpace)/mBfontD;
}
if (thumbw < bounds.width()){
mFontMis = (thumbw*mFontMis)/bounds.width();
p.setTextSize(mFontMis);
p.getTextBounds(mText, 0, mText.length(), bounds);
bounds.offset(0, -bounds.top);
}
dmx = ((endx-orgx)-bounds.width())/2;
dmy = (endy-orgy)-bounds.height();
spt = bounds.height();
p.setColor(0xff000000);
canvas.drawText(mText, orgx+dmx, endy-dmy, p);
int fm = (int)((mFontMis * mLfontD) / mBfontD);
p.setTextSize(fm);
p.getTextBounds(mText, 0, mVer.length(), bounds);
bounds.offset(0, -bounds.top);
dmx = ((endx-orgx)-bounds.width())/2;
int spy = (int)(mTotTxSpace -(mLfontD+mBfontD));
dmy = (int)((endy-orgy)-(bounds.height()+(((endy-orgy) *
spy)/mTotTxSpace)));
canvas.drawText(mVer, orgx+dmx, (endy-dmy)+(float)spt, p);
}
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mSplash != null) mSplash.recycle();
mSplash = null;
//Ridisegna
invalidate();
}
// // // // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // // // //
// Wait Timer
private Timer startTimer(Timer tt, int delay, int period) {
Timer itt = tt;
if (itt == null) {
itt = new Timer();
itt.schedule(new TimerTask() {
@Override
public void run() {
TimeCounter();
}
}, delay, period);
}
return itt;
}
private void stopTimers(Timer tt) {
if (tt != null) {
tt.cancel();
tt.purge();
}
}
//Calculate the residual time
private void TimeCounter(){
mDurata -= mPeriodo;
if (mDurata <= 0 && mCtx instanceof AppCompatActivity){
stopTimers(statusCommandsTimer);
((AppCompatActivity)mCtx).runOnUiThread(Timer_Tick);
}
}
//This function is necessary because I have to remove the splash screen and
//Remove the bitmap from the timer thread
private Runnable Timer_Tick = new Runnable() {
public void run() {
setEnabled(false);
setVisibility(INVISIBLE);
//for safety only as you are doing onClick
if(null!=padre && figlio != null)
padre.removeView(figlio);
if (mSplash != null) mSplash.recycle();
}
};
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
}
就是这样。欢迎任何建议或改进。