版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_23195583/article/details/54379232
先来看一下效果图:
有时一小块不起眼的功能就需要好多代码完成,这个可以做成框架用的,我这里仅仅在自己的app里使用了,这里还要感谢一下谷歌。来看一下借用的谷歌的代码:
// Since this is an object collection, use a FragmentStatePagerAdapter,
// and NOT a FragmentPagerAdapter.
public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {
public DemoCollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
Fragment fragment = new DemoObjectFragment();
Bundle args = new Bundle();
// Our object is just an integer :-P
args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
return 100;
}
@Override
public CharSequence getPageTitle(int position) {
return "OBJECT " + (position + 1);
}
}
挺好用的,嘿嘿。。。
好了看一下我的代码,我这里用的基本上就一个fragement+viewpager,先看一下activity的代码,我写的时候没有加注释,而且把调试代码删了。。。
首次进入轮播图其实不难,不建议用别人的依赖,核心代码不超过二百行。
package com.fanyafeng.recreation.activity;
import android.content.Intent;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import com.fanyafeng.recreation.R;
import com.fanyafeng.recreation.BaseActivity;
import com.fanyafeng.recreation.fragment.StartPagerFragment;
import com.fanyafeng.recreation.util.MyUtils;
import java.util.ArrayList;
import java.util.List;
//需要搭配Baseactivity,这里默认为Baseactivity,并且默认BaseActivity为包名的根目录
public class FirstStartActivity extends BaseActivity {
private ViewPager startViewPager;
private StartPagerAdapter startPagerAdapter;
private List<Fragment> fragmentList = new ArrayList<>();
private Button btnFirstStart;
private int maxX = 0;
private ImageView ivMovementCircle;
private static int[] startPage = new
int[]{R.drawable.start_one, R.drawable.start_two, R.drawable.start_three, R.drawable.start_four, R.drawable.start_five};
private int totalSize = 5;
private RelativeLayout layoutStartRoot;
private float moveCircleY = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first_start);
//这里默认使用的是toolbar的左上角标题,如果需要使用的标题为中心的采用下方注释的代码,将此注释掉即可
title = getString(R.string.title_activity_first_start);
isShowToolbar = false;
initView();
initData();
initCursorPosition();
}
//初始化UI控件
private void initView() {
layoutStartRoot = (RelativeLayout) findViewById(R.id.layoutStartRoot);
ivMovementCircle = (ImageView) findViewById(R.id.ivMovementCircle);
btnFirstStart = (Button) findViewById(R.id.btnFirstStart);
startViewPager = (ViewPager) findViewById(R.id.startViewPager);
for (int i = 0; i < totalSize; i++) {
fragmentList.add(new StartPagerFragment());
}
}
private void initCursorPosition() {
DisplayMetrics displayMetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
final int width = displayMetrics.widthPixels;
maxX = width;
Matrix matrix = new Matrix();
matrix.postTranslate(width / (totalSize + 1) - MyUtils.dip2px(this, 4), 0);
ivMovementCircle.setImageMatrix(matrix);
ivMovementCircle.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (ivMovementCircle.getY() != 0) {
moveCircleY = ivMovementCircle.getY();
for (int i = 0; i < totalSize; i++) {
ImageView imageView = new ImageView(FirstStartActivity.this);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.white_shape_circle));
imageView.setX(width / (totalSize + 1) * (i + 1) - MyUtils.dip2px(FirstStartActivity.this, 3));
imageView.setY(moveCircleY);
layoutStartRoot.addView(imageView);
ivMovementCircle.bringToFront();
}
} else {
return;
}
ivMovementCircle.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
//初始化数据
private void initData() {
startPagerAdapter = new StartPagerAdapter(getSupportFragmentManager(), fragmentList);
startViewPager.setAdapter(startPagerAdapter);
startViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (maxX != 0 && positionOffsetPixels != 0) {
float alph = 255 * positionOffsetPixels / maxX;
if (position == totalSize - 2) {
btnFirstStart.setVisibility(View.VISIBLE);
btnFirstStart.getBackground().setAlpha((int) alph);
btnFirstStart.setAlpha(alph);
} else {
btnFirstStart.setVisibility(View.GONE);
}
}
if (positionOffsetPixels != 0) {
ViewCompat.setTranslationX(ivMovementCircle, maxX / (totalSize + 1) * position + positionOffsetPixels / (totalSize + 1));
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
class StartPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragmentList;
public StartPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
super(fm);
this.fragmentList = fragmentList;
}
@Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("param1", String.valueOf(position));
bundle.putInt("param2", startPage[position]);
Fragment fragment = fragmentList.get(position);
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getCount() {
return fragmentList.size();
}
}
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
case R.id.btnFirstStart:
finish();
break;
case R.id.btnFirstFinish:
finish();
break;
}
startActivity(new Intent(this, MainActivity.class));
}
}
这里难点就两个吧,一个是让指示器的点随手势移动,一个是按钮的渐变,图片的加载交给fresco了。其实抽象一下就是获取偏移量,再根据轮播图的个数去进行处理。
这里点开看一下源码:
/**
* Callback interface for responding to changing state of the selected page.
*/
public interface OnPageChangeListener {
/**
* This method will be invoked when the current page is scrolled, either as part
* of a programmatically initiated smooth scroll or a user initiated touch scroll.
*
* @param position Position index of the first page currently being displayed.
* Page position+1 will be visible if positionOffset is nonzero.
* @param positionOffset Value from [0, 1) indicating the offset from the page at position.
* @param positionOffsetPixels Value in pixels indicating the offset from position.
*/
void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
/**
* This method will be invoked when a new page becomes selected. Animation is not
* necessarily complete.
*
* @param position Position index of the new selected page.
*/
void onPageSelected(int position);
/**
* Called when the scroll state changes. Useful for discovering when the user
* begins dragging, when the pager is automatically settling to the current page,
* or when it is fully stopped/idle.
*
* @param state The new scroll state.
* @see ViewPager#SCROLL_STATE_IDLE
* @see ViewPager#SCROLL_STATE_DRAGGING
* @see ViewPager#SCROLL_STATE_SETTLING
*/
void onPageScrollStateChanged(int state);
}
这里先去看一下英文,然后再去打log看一下调试信息就是到具体代表什么了,这里不是很建议用positionOffset这个偏移的比例,稍微有点坑,再有就是view的移动,这里用了一下v4包里的方法:
/**
* Sets the horizontal location of this view relative to its left position.
* This effectively positions the object post-layout, in addition to wherever the object's
* layout placed it.
*
* <p>Prior to API 11 this will have no effect.</p>
*
* @param value The horizontal position of this view relative to its left position,
* in pixels.
*/
public static void setTranslationX(View view, float value) {
IMPL.setTranslationX(view, value);
}
再来看一下xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/layoutStartRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.fanyafeng.recreation.activity.FirstStartActivity"
tools:showIn="@layout/activity_first_start">
<!--需要v4或者v7包,不过一般as创建的工程都默认存在,此处采用滑动嵌套布局,为了解决滑动冲突-->
<android.support.v4.view.ViewPager
android:id="@+id/startViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="@+id/btnFirstFinish"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:background="@drawable/avatar_round_bg"
android:text="跳过"
android:onClick="onClick"
android:textColor="@android:color/white"
android:textSize="12dp" />
<Button
android:id="@+id/btnFirstStart"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="40dp"
android:background="@drawable/rounded_button_bg"
android:text="开始"
android:onClick="onClick"
android:textColor="@android:color/white"
android:visibility="gone" />
<ImageView
android:id="@+id/ivMovementCircle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:scaleType="matrix"
android:src="@drawable/shape_circle" />
</RelativeLayout>
我这里的可移动指示点是定义在xml的,并没有去new,因为可以动的就一个是固定的,但是不可动的背景是不确定的,我去new的,还有个注意的地方就是高度的获取,就是需要了解一下android的绘画机制,需要进行两次测量才能确定view的高度进行绘制:
ivMovementCircle.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (ivMovementCircle.getY() != 0) {
moveCircleY = ivMovementCircle.getY();
for (int i = 0; i < totalSize; i++) {
ImageView imageView = new ImageView(FirstStartActivity.this);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.white_shape_circle));
imageView.setX(width / (totalSize + 1) * (i + 1) - MyUtils.dip2px(FirstStartActivity.this, 3));
imageView.setY(moveCircleY);
layoutStartRoot.addView(imageView);
ivMovementCircle.bringToFront();
}
} else {
return;
}
ivMovementCircle.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
这里设置了监听以后记得去remove掉,尤其有多个的时候。
ok,再来看一下fragment,这里没什么难的,就收参数然后去进行展示:
package com.fanyafeng.recreation.fragment;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import com.facebook.drawee.view.SimpleDraweeView;
import com.fanyafeng.recreation.R;
import com.fanyafeng.recreation.util.FrescoUtil;
public class StartPagerFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private int mParam2;
private SimpleDraweeView sdvStart;
public StartPagerFragment() {
// Required empty public constructor
}
public static StartPagerFragment newInstance(String param1, int param2) {
StartPagerFragment fragment = new StartPagerFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putInt(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getInt(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_start_pager, container, false);
sdvStart = (SimpleDraweeView) view.findViewById(R.id.sdvStart);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FrescoUtil.loadGifPicInApp(sdvStart, mParam2);
}
}
xml也很简单:
<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="com.fanyafeng.recreation.fragment.StartPagerFragment">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/sdvStart"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</RelativeLayout>