英文:
Couldn't run SplashScreen and OnBoarding screen together
问题
当我运行我的应用程序时,我看不到任何启动画面。我是从一个视频中学习的,我已经按照视频上的方式设置了我的AndroidManifest设置。我在清单文件中将我的启动画面定位在MainActivity之上,并将其设置为正常(就像我创建启动画面活动时一样),但它仍然不起作用。
我的AndroidManifest.xml:
<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:
<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(引导屏幕代码):
public class IntroActivity extends AppCompatActivity {
// ... 这里省略了代码的其余部分 ...
}
英文:
When I run my app, I can't see any Splash Screen.I did this from a video and I have set my AndroidManifest settings just like the one on the video. I located my SplashScreen on top of the MainActivity in Manifest file and set it to normal(just like the when I created my splash screen activity) but it still doesn't work.
My 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 screen codes):
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);
}
}
答案1
得分: 1
抱歉,我无法只返回翻译好的部分,因为您的文本中包含了很多代码和特定的技术内容,需要进行整体的解释和翻译。如果您有任何关于这些代码和内容的问题或需要进一步的解释,请随意提问。
英文:
I am new on android, and my solution could be not as normally you think is the right solution. First sorry for my bad english. In my opinion, the splash screen is only and elegant way for introduce you and your app. It must be fast and a short duration. I red a lot of solutions in internet but all pages and all snippets are at 90% the same (seems that many peoples have made cut / paste on the same first solution). So I decided to implement my own solution. Sorry for my raw code. I have implemented all in one Activity: and in your app you have to insert only this modifications:
-) Step one: activity_main.xml (main layout), include all in a 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>
The target FrameLayout (@id/frameContainer) is the splash screen container.
-) Step two: insert a bitmap in drawable directory, it should be the splash screen background, and in my example I have prepared also a rectangular space where insert my dynamic strings (for example "touch for start" and "Version n. 000.00.00"). My bitmap id is "@drawable/applogothumb", same in the string file, I have inserted a string "@string/toccasplash". On the bitmap I have also took the pixel coordinate of the rectangular space for the strings.
-) Step three: declaration and usage in the Main App:
@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();
....
....
As you can see all is managed in the CMainSplashBox class. Nothing else i required. In the meanwhile the Splash screen is displayed the app can finisc to build the code and continue the execution.
All is in the class, the managing on the click for close it and the timer for the time count.
The class is here. Before you see the class, remember that this is my first experiment and the code inside is made for my own scope but I think there is materia for work on it or, may be, someone can suggest me how improve this Idea...
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();
}
};
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
}
Thats all. Any suggestions or improvements are welcome.
答案2
得分: 0
SplashScreen
必须是您的启动活动。您的启动活动是IntroActivity
。已更新您的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" />
<!-- 设置 SplashScreen 为启动活动 -->
<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>
英文:
SplashScreen
must be your launcher activity. You have IntroActivity
as your launcher activity. Updated your 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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论