这分三层,当然你也可以实现更多层:
- 第 1层是背景层,以一张比较大的全景图做为背景,加上HorizontalScrollView实现滚动;
- 第2层是中间层,这层用来与第3层滑动做对比,由于与滑动速度不一样,加深视差效果,同样也是用HorizontalScrollView实现;
- 第3层是viewpager,这里就不多讲了。
XML代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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/backgroundLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.flobberworm.demo.parallax.ParallaxActivity">
<HorizontalScrollView
android:id="@+id/backgroundScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitXY"
android:background="@drawable/bg_ad" />
</LinearLayout>
</HorizontalScrollView>
<HorizontalScrollView
android:id="@+id/layerScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#00000000"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/view_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="120dp"
android:layout_marginTop="200dp"
android:gravity="center"
android:shadowColor="#000000"
android:shadowDy="1"
android:shadowRadius="5"
android:text="警察"
android:textColor="#ffffff"
android:textSize="32sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="120dp"
android:src="@mipmap/bruce" />
</LinearLayout>
<LinearLayout
android:id="@+id/view_2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00000000"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:gravity="center"
android:shadowColor="#000000"
android:shadowDy="1"
android:shadowRadius="5"
android:text="忍者"
android:textColor="#ffffff"
android:textSize="24sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="200dp"
android:src="@mipmap/tobe" />
</LinearLayout>
<RelativeLayout
android:id="@+id/view_3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#00000000">
<ImageView
android:id="@+id/iv_image_31"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="120dp"
android:src="@mipmap/pucca"
android:visibility="visible" />
<ImageView
android:id="@+id/iv_image_32"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="120dp"
android:layout_toRightOf="@id/iv_image_31"
android:src="@mipmap/abyo"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/view_4"
android:background="#00000000"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="150dp"
android:src="@mipmap/smile"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:background="#00000000"
android:id="@+id/view_5"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="80dp"
android:src="@mipmap/master_soo" />
</RelativeLayout>
</LinearLayout>
</HorizontalScrollView>
<android.support.v4.view.ViewPager
android:id="@+id/image_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:visibility="visible" />
</FrameLayout>
上面的只是Activity的布局,还有一些Adapter的子布局就传了,继续看代码:
public class ParallaxActivity extends AppCompatActivity {
private ViewPager viewPager;
private HorizontalScrollView backgroundScrollview;
private HorizontalScrollView layerScrollview;
private ParallaxAdapter adapter;
private int pageCount;
private int backgroundWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parallax);
setupView();
}
private void setupView() {
backgroundScrollview = (HorizontalScrollView) findViewById(R.id.backgroundScrollView);
layerScrollview = (HorizontalScrollView) findViewById(R.id.layerScrollView);
viewPager = (ViewPager) findViewById(R.id.image_pager);
backgroundScrollview.setHorizontalScrollBarEnabled(false);
layerScrollview.setHorizontalScrollBarEnabled(false);
setSecondPixels();
setupViewPager();
}
private void setupViewPager() {
adapter = new ParallaxAdapter(this);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
pageCount = adapter.getCount();
//缓动算法(学习中) 参考http://easings.net/zh-cn
//背景滚动
float backgroundOffset = Cubic.easeIn(positionOffset, 0, 1, 1);
float offset = (float) ((position + backgroundOffset) * 1.0 / pageCount);
int backgroundX = (int) (backgroundWidth * offset);
backgroundScrollview.scrollTo(backgroundX, 0);
//layer滚动
float layerRealOffset = Sine.easeIn(positionOffset, 0, 1, 1);
float layerOffset = (float) ((position + layerRealOffset) * 1.0 / pageCount);
int layerX = (int) (backgroundWidth * layerOffset);
layerScrollview.scrollTo(layerX, 0);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 解决HorizontalScrollView中match_parent无效问题
* 将第2层的总宽度与viewPager的总宽度保持一致,每一个view的宽高对应手机的宽高
*/
private void setSecondPixels() {
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
backgroundWidth = dm.widthPixels * 5;
ViewGroup.LayoutParams layoutParams;
View view1 = findViewById(R.id.view_1);
layoutParams = view1.getLayoutParams();
layoutParams.height = dm.heightPixels;
layoutParams.width = dm.widthPixels;
view1.setLayoutParams(layoutParams);
View view2 = findViewById(R.id.view_2);
layoutParams = view1.getLayoutParams();
layoutParams.height = dm.heightPixels;
layoutParams.width = dm.widthPixels;
view2.setLayoutParams(layoutParams);
View view3 = findViewById(R.id.view_3);
layoutParams = view1.getLayoutParams();
layoutParams.height = dm.heightPixels;
layoutParams.width = dm.widthPixels;
view3.setLayoutParams(layoutParams);
View view4 = findViewById(R.id.view_4);
layoutParams = view1.getLayoutParams();
layoutParams.height = dm.heightPixels;
layoutParams.width = dm.widthPixels;
view4.setLayoutParams(layoutParams);
View view5 = findViewById(R.id.view_5);
layoutParams = view1.getLayoutParams();
layoutParams.height = dm.heightPixels;
layoutParams.width = dm.widthPixels;
view5.setLayoutParams(layoutParams);
}