02.闪屏界面的开发
1、页面全屏
<activity
android:name=".SplashActivity"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
bug:
05-04 14:52:19.901 29429 29429 E AndroidRuntime: FATAL EXCEPTION: main
05-04 14:52:19.901 29429 29429 E AndroidRuntime: Process: cn.nubia.nubianewsclient, PID: 29429
05-04 14:52:19.901 29429 29429 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.nubia.nubianewsclient/cn.nubia.nubianewsclient.SplashActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3268)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3403)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:90)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1998)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.os.Looper.loop(Looper.java:215)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7504)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:500)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:865)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.support.v7.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:555)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.support.v7.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:518)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:466)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at cn.nubia.nubianewsclient.SplashActivity.onCreate(SplashActivity.java:11)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7193)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:7184)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1297)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3223)
05-04 14:52:19.901 29429 29429 E AndroidRuntime: ... 11 more
解决:
/**
* AppCompatActivity:
* V7下定义的action,作为actionbar向下兼容的效果
*
* 如果是AppCompatActivity的话,那么需要在清单文件中设置Theme.AppCompat
* 对于我们这个项目而言,我们不需要使用系统提供的ActionBar效果,所以我们可以不继承AppCompatActivity
*/
public class SplashActivity extends Activity {}
2、旋转动画
private void initAnimation() {
//1. 旋转动画
RotateAnimation rotateAnimation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);
rotateAnimation.setFillAfter(true);//保持动画结束时的状态
rotateAnimation.setDuration(2000);
//2. 缩放动画
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
scaleAnimation.setFillAfter(true);
scaleAnimation.setDuration(2000);
//3. 渐变动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setFillAfter(true);
alphaAnimation.setDuration(2000);
//4. 动画集合
//动画插入器:动画变化的速率设置
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateInterpolator());
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
rlSplash.startAnimation(animationSet);
}
动画特点
/**
* 1、帧动画:gif图片
* 2、补间动画:特性-->只改变View的绘制流程,不改变View的实际属性
* 3、属性动画,Android3.0,它能够改变View的实际属性
* 4、Activity切换的时候的动画效果overridePendingTransition();
* 5、Activity共享元素的动画
*/
03.新手引导页面数据的填充
//动画结束时监听,结束后跳转到主界面
animationSet.setAnimationListener(new SplashAnimationListener());
private class SplashAnimationListener implements Animation.AnimationListener {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
//1. 判断是否第一次使用这个软件
boolean isFirstEnter = PrefUtils.getBoolean(SplashActivity.this, "isFirstEnter", true);
Intent intent = new Intent();
if (isFirstEnter) {
//1.1 跳转新手引导界面
intent.setClass(SplashActivity.this, GuideActivity.class);
} else {
//1.2 跳转主界面
intent.setClass(SplashActivity.this, MainActivity.class);
}
startActivity(intent);
//2. 当前界面的消失
finish();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
}
去除标题栏
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_guide);
}
04.新手引导页面小圆点的增加
添加小圆点的布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.GuideActivity">
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp">
<LinearLayout
android:id="@+id/llDotContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<ImageView
android:id="@+id/iv_dot_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shape_dot_red" />
</RelativeLayout>
</RelativeLayout>
代码:
private void initDotContainer() {
for (int i = 0; i < mResIds.length; i++) {
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.shape_dot_grey);
//使用布局参数对象
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.leftMargin = 10;
if (i != 0) {
imageView.setLayoutParams(layoutParams);
}
llDotContainer.addView(imageView);
}
}
05.新手引导页面小红圆点位置的变化
//View的绘制流程
//measure-layout-draw
//onMeasure-onLayout-onDraw
//千万不要在Activity的onCreate方法中,获取一个控件的宽度、高度、位置等信息,此时View还没有走完绘制流程
//视图树:Android中管理View是通过树状结构进行管理
ivDotRed.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//当视图树中,所有的View对象都经过了layout方法之后,会进行的回调
@Override
public void onGlobalLayout() {
View viewFirst = llDotContainer.getChildAt(0);//获取第0个小圆点
View viewSecond = llDotContainer.getChildAt(1);//获取第0个小圆点
distance = viewSecond.getLeft() - viewFirst.getLeft();
System.out.println("distance=" + distance);
//使用原则,当我们获取到了我们想要的值之后,把视图树的监听移除
ivDotRed.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//ivRed.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
private class GuidePageChangeListener implements ViewPager.OnPageChangeListener {
//当ViewPager整个滑动过程中
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//改变小红点左边距
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) ivDotRed.getLayoutParams();
layoutParams.leftMargin = (int) ((positionOffset + position) * distance);
ivDotRed.setLayoutParams(layoutParams);
}
//滑动到某个界面时调用
@Override
public void onPageSelected(int position) {}
@Override
public void onPageScrollStateChanged(int state) {}
}
06.新手引导页面开始体验按钮功能实现
//滑动到某个界面时调用
@Override
public void onPageSelected(int position) {
if (position == mResIds.length - 1) {
btEnterMain.setVisibility(View.VISIBLE);
} else {
btEnterMain.setVisibility(View.GONE);
}
}