Android實現使用者引導介面

來源:互聯網
上載者:User

Android實現使用者引導介面

首先看,盜了超級課程表幾張圖

在眾多應用中,幾乎每一款應用都有自己的Splash使用者引導介面,該介面在使用者初次開機展示,之後不會顯示,主要向使用者展示新功能.

分析主要使用ViewPager+Indicator實現 主要是實現一個圓形指標,這個圓形指標繼承LinearLayout,需要有一些屬性可以自訂,比如指標的顏色,大小,邊距等 這個指標也可以自動滾動,比如應用在投影片展示的地方 指標是圓形的,需要我們自己繪製 這個圓形指標實現了ViewPager.OnPageChangeListener介面實現定義自訂屬性
屬性的意思見名字就可以知道了
                                                                
定義自訂變數,從布局檔案中解析進來,此外,如果布局檔案沒有使用,應該有一個預設的常量.
定義預設常量
 private static final int DEFAULT_CIRCLE_SPACING = 5;    private static final int DEFAULT_CIRCLE_COLOR=Color.WHITE;    private static final int DEFAULT_CIRCLE_SIZE=3;    private static final boolean DEFAULT_CIRCLE_AUTO_SCROLL=false;    private static final int DEFAULT_CIRCLE_SCROLL_DELAY_TIME=3000;    private static final boolean DEFAULT_CIRCLE_SCROLL_ANIMATION=true;

定義用於儲存自訂屬性的變數

    private int mSpacing;    private int mSize;    private int mFillColor;    private int mStrokeColor;    private boolean mAutoScroll;    private int mDelayTime;    private boolean mIsAnimation;

定義其他輔助變數,比如Canvas,Bitmap,Paint等,用於繪製圓形指標

    private static final int CIRCLE_STROKE_WIDTH =1;    private static final int BITMAP_PADDING =2; private ViewPager mViewPager;    private int mCount;    private int mLastIndex = 0;    private Canvas mCanvas;    private Paint mPaint;    private Bitmap mSelectBitmap;    private Bitmap mUnselectBitmap;

將自訂屬性進行解析賦值給對應變數

private void initCustomParams(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleIndicator);        try {            mSpacing = typedArray.getDimensionPixelSize(R.styleable.CircleIndicator_circle_spacing, DEFAULT_CIRCLE_SPACING);            mFillColor=typedArray.getColor(R.styleable.CircleIndicator_circle_fill_color,DEFAULT_CIRCLE_COLOR);            mStrokeColor=typedArray.getColor(R.styleable.CircleIndicator_circle_stroke_color,DEFAULT_CIRCLE_COLOR);            mSize= typedArray.getDimensionPixelSize(R.styleable.CircleIndicator_circle_radius, DEFAULT_CIRCLE_SIZE);            mAutoScroll= typedArray.getBoolean(R.styleable.CircleIndicator_circle_auto_scroll, DEFAULT_CIRCLE_AUTO_SCROLL);            mDelayTime=typedArray.getInt(R.styleable.CircleIndicator_circle_scroll_delay_time,DEFAULT_CIRCLE_SCROLL_DELAY_TIME);            mIsAnimation=typedArray.getBoolean(R.styleable.CircleIndicator_circle_scroll_animation,DEFAULT_CIRCLE_SCROLL_ANIMATION);        } finally {            typedArray.recycle();        }    }

我們的指標是自己繪製出來的,接下來繪製圓形指標

    private void init() {        setOrientation(HORIZONTAL);        mPaint = new Paint();        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);        mPaint.setStrokeWidth(dip2px(CIRCLE_STROKE_WIDTH));        mPaint.setColor(mFillColor);        int size=dip2px(mSize+ BITMAP_PADDING + BITMAP_PADDING);        int radius=dip2px(mSize / 2);        int centerPoint=radius+ BITMAP_PADDING;        mSelectBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        mUnselectBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        mCanvas = new Canvas();        mCanvas.setBitmap(mSelectBitmap);        mCanvas.drawCircle(centerPoint, centerPoint, radius, mPaint);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setColor(mStrokeColor);        mCanvas.setBitmap(mUnselectBitmap);        mCanvas.drawCircle(centerPoint, centerPoint, radius, mPaint);    }

實現構造方法,最終調用三個參數的構造方法,並調用相關函數進行初始化

 public CircleIndicator(Context context) {        this(context, null);    }    public CircleIndicator(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CircleIndicator(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initCustomParams(context, attrs);        init();    }

實現指標相關邏輯

首先需要初始化指標的位置,應該是ViewPager的第一頁,即初始化位置為0,調用initIndicator,並設定指標的背景圖為選中狀態.記錄上次指標的位置即當前位置. removeIndicator移出指標只要移出當前類的所有子View即可 updateIndicator需要將上次的位置背景圖設定為未選中,當前位置設定未選中,並記錄上次位置為當前位置 addIndicator需要將圓形指標的數目傳入,其值為ViewPager的頁數,並建立ImageView設定背景圖為未選中的時候的圖,並設定外邊距,將其添加到當前類的子View中,如果設定了自動滾動,還需要進行自動滾動 setViewPager函數進行一些初始化操作
public void setViewPager(ViewPager viewPager) {        mViewPager = viewPager;        mViewPager.addOnPageChangeListener(this);        if (mViewPager != null) {            mCount = mViewPager.getAdapter().getCount();            addIndicator(mCount);        }    }    private void addIndicator(int count) {        removeIndicator();        if (count <= 0)            return;        for (int i = 0; i < count; i++) {            ImageView imageView = new ImageView(getContext());            LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);            params.leftMargin = mSpacing/2;            params.rightMargin = mSpacing/2;            imageView.setImageBitmap(mUnselectBitmap);            addView(imageView, params);        }        initIndicator();        if(mAutoScroll){            sendScrollMessage(mDelayTime);        }    }    private void initIndicator() {        ((ImageView) getChildAt(0)).setImageBitmap(mSelectBitmap);        mLastIndex=0;    }    private void removeIndicator() {        removeAllViews();    }    private void updateIndicator(int position) {        if (position != mLastIndex) {            ((ImageView) getChildAt(mLastIndex)).setImageBitmap(mUnselectBitmap);            ((ImageView) getChildAt(position)).setImageBitmap(mSelectBitmap);        }        mLastIndex = position;    }

實現自動滾動,主要通過Handler進行延時實現

 private Handler mHandler=new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what) {                case SCROLL_WHAT:                    scrollOnce();                    sendScrollMessage(mDelayTime);                    break;            }        }    };    public void scrollOnce() {        PagerAdapter adapter = mViewPager.getAdapter();        if (adapter == null) {            return;        }        int nextIndex=mViewPager.getCurrentItem();        ++nextIndex;        if(nextIndex >=mCount){            nextIndex =0;        }        updateIndicator(nextIndex);        mViewPager.setCurrentItem(nextIndex, mIsAnimation);    }    private void sendScrollMessage(long delayTimeInMills) {        mHandler.removeMessages(SCROLL_WHAT);        mHandler.sendEmptyMessageDelayed(SCROLL_WHAT, delayTimeInMills);    }

實現相關getter和setter函數

 private void setAutoScroll(boolean autoScroll){        if (autoScroll){            sendScrollMessage(mDelayTime);        }else{            mHandler.removeMessages(SCROLL_WHAT);        }        mAutoScroll=autoScroll;    }    public boolean isAutoScroll() {        return mAutoScroll;    }    public int getDelayTime() {        return mDelayTime;    }    public void setDelayTime(int delayTime) {        mDelayTime = delayTime;    }    public boolean isAnimation() {        return mIsAnimation;    }    public void setIsAnimation(boolean isAnimation) {        mIsAnimation = isAnimation;    }

實現介面相關函數

 @Override    public void onPageScrolled(int i, float v, int i1) {    }    @Override    public void onPageSelected(int position) {        updateIndicator(position);    }    @Override    public void onPageScrollStateChanged(int i) {    }

以及一個單位轉換的工具函數

private int dip2px(int dip) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());    }
使用
            
 private void initView() {        mViewPager= (ViewPager) findViewById(R.id.viewpager);        mCircleIndicator= (CircleIndicator) findViewById(R.id.circle_indicator);        mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {            private int[] resId={R.mipmap.ic_help_view_1,R.mipmap.ic_help_view_2,R.mipmap.ic_help_view_3,R.mipmap.ic_help_view_4};            private Map mFragments=new HashMap();            @Override            public Fragment getItem(int i) {                Fragment fragment=mFragments.get(i);                if(fragment==null){                    fragment=BlankFragment.newInstance(resId[i],i,resId.length);                    mFragments.put(i,fragment);                }                return fragment;            }            @Override            public int getCount() {                return resId.length;            }        });        mCircleIndicator.setViewPager(mViewPager);    }
package cn.edu.zafu.splash;import android.content.Intent;import android.os.Bundle;import android.support.v4.app.Fragment;import android.util.TypedValue;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.RelativeLayout;public class BlankFragment extends Fragment {    private static final String IMAGE_ID = imageId;    private static final String CUCRNT = curcent;    private static final String TOTAL = total;    private int mImageId;    private int mCurcent;    private int mTotal;    public static BlankFragment newInstance(int imageId,int current,int total) {        BlankFragment fragment = new BlankFragment();        Bundle args = new Bundle();        args.putInt(IMAGE_ID, imageId);        args.putInt(CUCRNT, current);        args.putInt(TOTAL, total);        fragment.setArguments(args);        return fragment;    }    public BlankFragment() {    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            mImageId = getArguments().getInt(IMAGE_ID);            mCurcent = getArguments().getInt(CUCRNT);            mTotal = getArguments().getInt(TOTAL);        }    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view= inflater.inflate(R.layout.fragment_blank, container, false);        return view;    }    @Override    public void onViewCreated(View view, Bundle savedInstanceState) {        getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        super.onViewCreated(view, savedInstanceState);        ImageView imageView= (ImageView) view.findViewById(R.id.image);        imageView.setImageResource(mImageId);        if(mCurcent==mTotal-1){            RelativeLayout relativeLayout= (RelativeLayout) view.findViewById(R.id.relativelayout);            ImageButton button=new ImageButton(getActivity().getApplicationContext());            button.setBackgroundResource(R.drawable.last_button_selector);            RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);            params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);            params.addRule(RelativeLayout.CENTER_HORIZONTAL);            params.bottomMargin=dip2px(80);            relativeLayout.addView(button,params);            button.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    int versionCode=Util.getAppVersionCode(getActivity());                    Util.set(getActivity(),Util.FILE_NAME,versionCode+,true);                    Intent intent=new Intent(getActivity(),SecondActivity.class);                    startActivity(intent);                    getActivity().finish();                }            });        }    }    private int dip2px(int dip) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getActivity().getResources().getDisplayMetrics());    }}

如果要實現是否初次開機,如果是才顯示的話需要加一些邏輯判斷,如果目前的版本號已經持久化了,則直接跳過,這個資料是在Splash頁面最後一個按鈕點擊事件裡處理的

private boolean ignoreSplash() {        if(Util.contatins(this, Util.FILE_NAME, Util.getAppVersionCode(this) + )){            Intent intent=new Intent(MainActivity.this,SecondActivity.class);            startActivity(intent);            this.finish();            return true;        }        return false;    }
public void onClick(View v) {                    int versionCode=Util.getAppVersionCode(getActivity());                    Util.set(getActivity(),Util.FILE_NAME,versionCode+,true);                    Intent intent=new Intent(getActivity(),SecondActivity.class);                    startActivity(intent);                    getActivity().finish();                }
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.