#java #android #splash-screen
#java #Android #экран-заставка #ява
Вопрос:
Когда я запускаю свое приложение, я не вижу никакой заставки.Я сделал это из видео, и я установил настройки своего AndroidManifest точно так же, как на видео. Я разместил свой SplashScreen поверх MainActivity в файле манифеста и установил его в обычное состояние (точно так же, как при создании моей заставки), но он все еще не работает.
Мой 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 (Коды на экране ввода):
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. Привет, попробуйте удалить эти строки, если (restorePrefData()) { Намерение MainActivity = новое намерение(getApplicationContext(),MainActivity.class ); startActivity (MainActivity); finish(); } Я думаю, что это может быть проблемой, из-за которой ваш просмотр не виден
2. если я сделаю это, я должен удалить всю нижнюю часть функций в строках, которые вы сказали.
3. я запускаю свое приложение на своем реальном телефоне, а не на виртуальной машине. я только что понял, что есть 2 одинаковых приложения. почему это произошло?
Ответ №1:
Я новичок в Android, и мое решение может быть не таким, как обычно, вы считаете правильным решением. Сначала извините за мой плохой английский. На мой взгляд, заставка — это единственный и элегантный способ представить вас и ваше приложение. Это должно быть быстро и на короткое время. Я нашел много решений в Интернете, но все страницы и все фрагменты на 90% одинаковы (кажется, что многие люди вырезали / вставляли одно и то же первое решение). Поэтому я решил реализовать свое собственное решение. Извините за мой необработанный код. Я реализовал все в одном действии: и в вашем приложении вы должны вставить только эти изменения:
-) Шаг первый: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, оно должно быть фоном заставки, и в моем примере я подготовил также прямоугольное пространство, куда вставляю свои динамические строки (например, «нажмите для запуска» и «Версия n. 000.00.00»). Мой идентификатор растрового изображения «@drawable / applogothumb», такой же в файле string, я вставил строку «@string /toccasplash». На растровом изображении я также взял пиксельную координату прямоугольного пространства для строк.
-) Шаг третий: объявление и использование в основном приложении:
@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. Больше мне ничего не требовалось. В то время как отображается экран-заставка, приложение может завершить сборку кода и продолжить выполнение.
Все находится в классе, управление по щелчку для его закрытия и таймер для отсчета времени.
Класс здесь. Прежде чем вы увидите класс, помните, что это мой первый эксперимент, и код внутри сделан для моей собственной области, но я думаю, что есть материал для работы над ним или, может быть, кто-то может подсказать мне, как улучшить эту идею…
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 amp;amp; 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 amp;amp; figlio != null)
padre.removeView(figlio);
if (mSplash != null) mSplash.recycle();
}
};
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
// // // // // // // // // // // // // // // // // // // //
}
Вот и все. Любые предложения или улучшения приветствуются.
Ответ №2:
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" />
// 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>