私藏的安卓开发过程中好用的组件

HeightWrapListView,HeightWrapListViewUtils

说明:高度自适应的ListVive

package com.ruidonghy.widget.listview;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

/**
 * Created by zhou on 2017/12/21.
 */

public class HeightWrapListView extends ListView {

    public HeightWrapListView(Context context) {
        super(context);
    }

    public HeightWrapListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
}


package com.ruidonghy.widget.listview;

import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;

/**
 * Created by zhou on 2017/12/21.
 */

public class HeightWrapListViewUtils {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        // 获取ListView对应的Adapter
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            return;

        }
        int totalHeight = 0;

        for (int i = 0; i < listAdapter.getCount(); i++) { // listAdapter.getCount()返回数据项的数目
            View listItem = listAdapter.getView(i, null, listView);
            listItem.measure(0, 0); // 计算子项View 的宽高
            totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
        }
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight
                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        // listView.getDividerHeight()获取子项间分隔符占用的高度
        // params.height最后得到整个ListView完整显示需要的高度
        listView.setLayoutParams(params);
    }
}

复制代码

数据解释类

说明:为空断网加载中等

package com.ruidonghy.widget.prompt;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.TextView;

import com.ruidonghy.widget.R;
import com.ruidonghy.zbase.base.BaseWidget;

/**
 * Created by zhou on 2017/12/22.
 */

public class DataNullView extends BaseWidget implements IChildView{
    private ImageView mDataNullIcon;
    private TextView mDataNullContent;
    public DataNullView(Context context) {
        super(context);
    }

    public DataNullView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void initView() {
        mDataNullIcon = getView().findViewById(R.id.datanull_icon);
        mDataNullContent = getView().findViewById(R.id.datanull_content);
    }

    @Override
    public void initInnerEvent() {

    }

    public void setDataNullIcon(int dataNullDrawable){
        mDataNullIcon.setImageResource(dataNullDrawable);
    }
    public void setDataNullTip(int dataNullTip){
        mDataNullContent.setText(dataNullTip);
    }

    @Override
    public int getLayoutId() {
        return R.layout.view_datanull;
    }

    @Override
    public void gone() {
        setVisibility(GONE);
    }

    @Override
    public void show() {
        setVisibility(VISIBLE);
    }
}

package com.ruidonghy.widget.prompt;

/**
 * Created by zhou on 2017/12/22.
 */

public interface IChildView {
    void gone();
    void show();
}

package com.ruidonghy.widget.prompt;

import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.view.View;

/**
 * Created by abbott on 2017/12/7.
 */

public interface IPromptView {

    /**
     * 初始化 提示控件
     * @param loadingTips
     * @param dataNullTips
     * @param dataNullDrawable
     * @param onNoNetClickListener
     */
    void init(int loadingTips,int dataNullTips,int dataNullDrawable,View.OnClickListener onNoNetClickListener);

    void init(View.OnClickListener onNoNetClickListener);

    /**
     * 显示加载中
     */
    void showLoading();

    /**
     * 显示数据为空
     */
    void showDataNull();

    /**
     * 显示网络错误
     */
    void showNetError();

    /**
     * 隐藏提示弹窗
     */
    void hidden();
}

package com.ruidonghy.widget.prompt;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;
import android.widget.TextView;

import com.ruidonghy.widget.R;
import com.ruidonghy.zbase.base.BaseWidget;

/**
 * Created by zhou on 2017/12/22.
 */

public class LoadingView extends BaseWidget implements IChildView{
    private RotateLoading mLoading;
    private TextView mLoadingTips;
    public LoadingView(Context context) {
        super(context);
    }

    public LoadingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void initView() {
        mLoading = getView().findViewById(R.id.rotate_view);
        mLoadingTips = getView().findViewById(R.id.loading_tips);
    }

    @Override
    public void initInnerEvent() {

    }

    public void setLoadingTips(int loadingTips){
        mLoadingTips.setText(loadingTips);
    }

    @Override
    public int getLayoutId() {
        return R.layout.view_loading;
    }

    @Override
    public void gone() {
        if(mLoading.isStart()){
            mLoading.stop();
        }
        setVisibility(GONE);
    }

    @Override
    public void show() {
        setVisibility(VISIBLE);
        if(!mLoading.isStart()){
            mLoading.start();
        }
    }
}

package com.ruidonghy.widget.prompt;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.TextView;

import com.ruidonghy.widget.R;
import com.ruidonghy.zbase.base.BaseWidget;

/**
 * Created by zhou on 2017/12/22.
 */

public class NetErrorView extends BaseWidget implements IChildView{
    private TextView mNeterrorRefresh;
    public NetErrorView(Context context) {
        super(context);
    }

    public NetErrorView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void initView() {
        mNeterrorRefresh = getView().findViewById(R.id.neterror_refresh);
    }

    @Override
    public void initInnerEvent() {

    }

    @Override
    public int getLayoutId() {
        return R.layout.view_neterror;
    }

    public void setNetErrorClickListener(OnClickListener netErrorClickListener){
        mNeterrorRefresh.setOnClickListener(netErrorClickListener);
    }

    @Override
    public void gone() {
        setVisibility(GONE);
    }

    @Override
    public void show() {
        setVisibility(VISIBLE);
    }
}

package com.ruidonghy.widget.prompt;

import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;

import com.ruidonghy.widget.R;
import com.ruidonghy.zbase.base.BaseWidget;

import java.util.ArrayList;

/**
 * 公共提示加载、缺省view
 * Created by yunlong on 2017/12/7.
 *
 * 修改此类by zhou 2017-12-22
 *
 *
 * 提示文字初始化一次,有则用新的,没有则用默认的
 * 网络错点击刷新监听需要开始时初始化。
 */

public class PromptView extends BaseWidget implements IPromptView {
    private DataNullView mDataNullView;
    private NetErrorView mNetErrorView;
    private LoadingView mLoadingView;
    private ArrayList<IChildView> mViewList;
    public PromptView(Context context) {
        super(context);
    }

    public PromptView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void initView() {
        mViewList = new ArrayList<>();
        mDataNullView = getView().findViewById(R.id.datanull_view);
        mNetErrorView = getView().findViewById(R.id.neterror_view);
        mLoadingView = getView().findViewById(R.id.loading_view);
        mViewList.add(mDataNullView);
        mViewList.add(mNetErrorView);
        mViewList.add(mLoadingView);
    }

    @Override
    public void initInnerEvent() {

    }

    @Override
    public void init(OnClickListener onNoNetClickListener) {
        mNetErrorView.setNetErrorClickListener(onNoNetClickListener);
    }

    @Override
    public void init(int loadingTips, int dataNullTips, int dataNullDrawable, OnClickListener onNoNetClickListener) {
        mLoadingView.setLoadingTips(loadingTips);
        mDataNullView.setDataNullTip(dataNullTips);
        mDataNullView.setDataNullIcon(dataNullDrawable);
        mNetErrorView.setNetErrorClickListener(onNoNetClickListener);
    }



    @Override
    public void showLoading() {
        setVisibility(VISIBLE);
        show(mLoadingView);
    }

    @Override
    public void showDataNull() {
        setVisibility(VISIBLE);
        show(mDataNullView);
    }


    @Override
    public void showNetError() {
        setVisibility(VISIBLE);
        show(mNetErrorView);
    }


    @Override
    public void hidden() {
        mLoadingView.gone();
        setVisibility(GONE);
    }

    @Override
    public int getLayoutId() {
        return R.layout.view_prompt;
    }


    /**
     * 内部方法,show传进来的参数,gone其他。
     * @param childView
     */
    private void show(IChildView childView){
        childView.show();
        for(int i=0;i<mViewList.size();i++){
            if(mViewList.get(i)!=childView){
                mViewList.get(i).gone();
            }
        }
    }

}

package com.ruidonghy.widget.prompt;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.ruidonghy.widget.R;


/**
 * RotateLoading
 * Created by Victor on 2015/4/28.
 */
public class RotateLoading extends View {

    private static final int DEFAULT_WIDTH = 6;
    private static final int DEFAULT_SHADOW_POSITION = 2;
    private static final int DEFAULT_SPEED_OF_DEGREE = 10;

    private Paint mPaint;

    private RectF loadingRectF;
    private RectF shadowRectF;

    private int topDegree = 10;
    private int bottomDegree = 190;

    private float arc;

    private int width;

    private boolean changeBigger = true;

    private int shadowPosition;

    private boolean isStart = false;

    private int color;

    private int speedOfDegree;

    private float speedOfArc;

    public RotateLoading(Context context) {
        super(context);
        initView(context, null);
    }

    public RotateLoading(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public RotateLoading(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        color = Color.WHITE;
        width = dpToPx(context, DEFAULT_WIDTH);
        shadowPosition = dpToPx(getContext(), DEFAULT_SHADOW_POSITION);
        speedOfDegree = DEFAULT_SPEED_OF_DEGREE;

        if (null != attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RotateLoading);
            color = typedArray.getColor(R.styleable.RotateLoading_loading_color, Color.WHITE);
            width = typedArray.getDimensionPixelSize(R.styleable.RotateLoading_loading_width, dpToPx(context, DEFAULT_WIDTH));
            shadowPosition = typedArray.getInt(R.styleable.RotateLoading_shadow_position, DEFAULT_SHADOW_POSITION);
            speedOfDegree = typedArray.getInt(R.styleable.RotateLoading_loading_speed, DEFAULT_SPEED_OF_DEGREE);
            typedArray.recycle();
        }
        speedOfArc = speedOfDegree / 4;
        mPaint = new Paint();
        mPaint.setColor(color);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(width);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        arc = 10;

        loadingRectF = new RectF(2 * width, 2 * width, w - 2 * width, h - 2 * width);
        shadowRectF = new RectF(2 * width + shadowPosition, 2 * width + shadowPosition, w - 2 * width + shadowPosition, h - 2 * width + shadowPosition);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isStart) {
            return;
        }

        mPaint.setColor(Color.parseColor("#1a000000"));
        canvas.drawArc(shadowRectF, topDegree, arc, false, mPaint);
        canvas.drawArc(shadowRectF, bottomDegree, arc, false, mPaint);

        mPaint.setColor(color);
        canvas.drawArc(loadingRectF, topDegree, arc, false, mPaint);
        canvas.drawArc(loadingRectF, bottomDegree, arc, false, mPaint);

        topDegree += speedOfDegree;
        bottomDegree += speedOfDegree;
        if (topDegree > 360) {
            topDegree = topDegree - 360;
        }
        if (bottomDegree > 360) {
            bottomDegree = bottomDegree - 360;
        }

        if (changeBigger) {
            if (arc < 160) {
                arc += speedOfArc;
                invalidate();
            }
        } else {
            if (arc > speedOfDegree) {
                arc -= 2 * speedOfArc;
                invalidate();
            }
        }
        if (arc >= 160 || arc <= 10) {
            changeBigger = !changeBigger;
            invalidate();
        }
    }

    public void setLoadingColor(int color) {
        this.color = color;
    }

    public int getLoadingColor() {
        return color;
    }

    public void start() {
        startAnimator();
        isStart = true;
        invalidate();
    }

    public void stop() {
        stopAnimator();
        invalidate();
    }

    public boolean isStart() {
        return isStart;
    }

    private void startAnimator() {
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX", 0.0f, 1);
        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 0.0f, 1);
        scaleXAnimator.setDuration(300);
        scaleXAnimator.setInterpolator(new LinearInterpolator());
        scaleYAnimator.setDuration(300);
        scaleYAnimator.setInterpolator(new LinearInterpolator());
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
        animatorSet.start();
    }

    private void stopAnimator() {
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX", 1, 0);
        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 1, 0);
        scaleXAnimator.setDuration(300);
        scaleXAnimator.setInterpolator(new LinearInterpolator());
        scaleYAnimator.setDuration(300);
        scaleYAnimator.setInterpolator(new LinearInterpolator());
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                isStart = false;
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animatorSet.start();
    }


    public int dpToPx(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources().getDisplayMetrics());
    }

}



view_datanull.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/datanull_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/no_data" />
    <TextView
        android:id="@+id/datanull_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_12"
        android:textColor="@color/color_CCC"
        android:textSize="@dimen/sp_13"
        android:text="@string/no_data_txt" />
</LinearLayout>


view_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <com.ruidonghy.widget.prompt.RotateLoading
        android:id="@+id/rotate_view"
        android:layout_width="@dimen/rotateloading_width"
        android:layout_height="@dimen/rotateloading_height"
        app:loading_color="@color/color_loading"
        app:loading_speed="10"
        app:loading_width="3dp" />
    <TextView
        android:id="@+id/loading_tips"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_12"
        android:text="@string/prompt_loading"
        android:textColor="@color/color_555"
        android:textSize="@dimen/sp_13" />
</LinearLayout>

neterror_refresh.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/neterror_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/no_net" />
    <TextView
        android:id="@+id/neterror_tip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_12"
        android:text="@string/un_connect_net"
        android:textColor="@color/color_555"
        android:textSize="@dimen/sp_13" />
    <TextView
        android:id="@+id/neterror_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/margin_12"
        android:textColor="@color/color_CCC"
        android:textSize="@dimen/sp_13"
        android:text="@string/no_net_txt" />

    <TextView
        android:id="@+id/neterror_refresh"
        android:layout_width="@dimen/refresh_width"
        android:layout_height="@dimen/refresh_height"
        android:layout_marginTop="@dimen/margin_12"
        android:background="@drawable/refresh_shape"
        android:gravity="center"
        android:text="点击刷新"
        android:textColor="@color/color_555"
        android:textSize="@dimen/sp_14" />
</LinearLayout>

view_prompt.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_white"
    android:gravity="center"
    android:orientation="vertical">
    <com.ruidonghy.widget.prompt.DataNullView
        android:id="@+id/datanull_view"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <com.ruidonghy.widget.prompt.NetErrorView
        android:id="@+id/neterror_view"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <com.ruidonghy.widget.prompt.LoadingView
        android:id="@+id/loading_view"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>


attrs.xml
<!-- 圆形加载进度条 -->
    <declare-styleable name="RotateLoading">
        <attr name="loading_width" format="dimension"/>
        <attr name="loading_color" format="color"/>
        <attr name="shadow_position" format="integer"/>
        <attr name="loading_speed" format="integer"/>
    </declare-styleable>

复制代码

RoundShadowDrawable

说明:圆角Drawable

package com.ruidonghy.widget.shadow;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;

/**
 * Created by zcz
 */

public class RoundShadowDrawable extends Drawable {
    Paint paint;
    Paint paintShadow;
    Path path;
    RectF rectF;
    int x = 20;
    int y = 20;
    int radius = 20;
    public RoundShadowDrawable() {
        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);

        paintShadow = new Paint();
        paintShadow.setColor(Color.WHITE);
        paintShadow.setAntiAlias(true);
        path = new Path();
    }

    public void setColor(int color) {
        // 设定阴影(柔边, X 轴位移, Y 轴位移, 阴影颜色)
        paintShadow.setShadowLayer(20, 0, 2, color);
        invalidateSelf();
    }

    public void setRadius(int radius) {
        this.radius = radius;
        invalidateSelf();
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawPath(path, paintShadow);
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        path.reset();
        rectF = new RectF(x, y+2, bounds.width() - x, bounds.height()-y);
        path.addRoundRect(rectF, new float[]{radius, radius, radius, radius, radius, radius, radius, radius}, Path.Direction.CW);
    }

    @Override
    public void setAlpha(int i) {

    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

复制代码

WillUriRouter

说明:自己写的启动其他组件的Router

package com.ruidonghy.zbase.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Parcelable;
import android.support.v4.app.Fragment;

/**
 * Created by zhou on 2017/11/6 16:30 .
 */

public class WillUriRouter {

    //启动activity
    public static <T extends Parcelable>void startAct(Context context,String action, T message){
        Intent intent = new Intent(action);
        intent.putExtra("data",message);
        if(context instanceof Activity){//为了后面添加动画,暂时还没添加
            ((Activity)context).startActivity(intent);
        }else{
            context.startActivity(intent);
        }
    }

    //启动activity
    public static <T extends Parcelable>void startActForFlags(Context context,String action, T message){
        Intent intent = new Intent(action);
        intent.putExtra("data",message);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        if(context instanceof Activity){//为了后面添加动画,暂时还没添加
            ((Activity)context).startActivity(intent);
        }else{
            context.startActivity(intent);
        }
    }
    //启动activity
    public static <T extends Parcelable>void startAct(Context context,String action, T message,int other){
        Intent intent = new Intent(action);
        intent.putExtra("data",message);
        intent.putExtra("other",other);
        if(context instanceof Activity){//为了后面添加动画,暂时还没添加
            ((Activity)context).startActivity(intent);
        }else{
            context.startActivity(intent);
        }
    }

    //启动activity以startActivityForResult的方式
    public static <T extends Parcelable>void startActForResult(Activity context,String action, T message,int requestCode){
        Intent intent = new Intent(action);
        intent.putExtra("data",message);
        if(context instanceof Activity){//为了后面添加动画,暂时还没添加
            ((Activity)context).startActivityForResult(intent,requestCode);
        }else{
            context.startActivityForResult(intent,requestCode);
        }
    }

    //启动activity以startActivityForResult的方式
    public static <T extends Parcelable>void startActForResult(Fragment fragment,String action, T message,int requestCode){
        Intent intent = new Intent(action);
        intent.putExtra("data",message);
        fragment.startActivityForResult(intent,requestCode);
    }

//<intent-filter>
//    <action android:name="android.intent.action.VIEW"/>
//    <category android:name="android.intent.category.DEFAULT"/>
//    <category android:name="android.intent.category.BROWSABLE"/>
//    <data
//    android:host="shortvideo"
//    android:pathPrefix="/share"
//    android:scheme="xiuba"/>
//</intent-filter>

//    uri.getQueryParameter("message");


}
复制代码

WillRequestUtil ,CommParamsModel ,

说明:程序中用到的公参的处理方式

  1. 加密
  2. 公参获取
  3. 公参传递
package com.ruidonghy.zbase.utils;

import com.ruidonghy.zbase.data.CommParamsModel;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by zhou on 2017/11/8 11:35 .
 */

public class WillRequestUtil {

    /**
     * 即需要公参也需要加密
     * @param params
     * @return
     */
    public static Map<String,String> getAppCommParamsASecurity(Map<String, String> params){
        return getSecurity(getCommParams(params));//先增加公参,后安全认证
    }

    /**
     * 公参获取方法
     * @param params
     * @return
     */
    private static Map<String,String> getCommParams(Map<String, String> params){
        params.put("app_imei", CommParamsModel.instance().getAppImei());
        params.put("app_type",CommParamsModel.instance().getAppType());
        params.put("app_version",CommParamsModel.instance().getAppVersion());
        return params;
    }

    /**
     * 公共加密方法
     * @param params
     * @return
     */
    private static Map<String, String> getSecurity(Map<String, String> params){
        Map<String,String> map = new HashMap<String,String>();
        String json = WillJsonParseUtils.obj2JsonStr(params, "");
        LogUtils.d("okhttp请求入参--->json=",json);
        //随机生成16位的AES密钥key
        String aesKey = RandomUtil.getRandom(16);
        //将json加密  先加密然后Base64转码,然后返回data
        String data = null;
        try {
            data = AESUtils.encodeAES(json, aesKey);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtils.e("AES encode error");
        }

        //将AES密钥key用rsa加密
        String dataKey = null;
        try {
//            dataKey = new String(Base64.encode(RSAUtils.encrypt(aesKey.getBytes(), RSAUtils.getPublicKey(AppConstants.PUBLICKEY_SERVER)),Base64.DEFAULT),"UTF-8");
            LogUtils.d("aesKey="+aesKey);
            dataKey = RsaUtils.encryptByPublic(aesKey);
        } catch (Exception e) {
            e.printStackTrace();
        }

        map.put("data_key", dataKey);
        map.put("data", data);

        return map;
    }
}



package com.ruidonghy.zbase.data;

/**
 * 定义此类为了不让程序多次进行imei 和appversion的获取
 * Created by zhou on 2017/11/13 10:42 .
 */

public class CommParamsModel {
    private CommParamsModel(){}
    private static class ParamsHolder{
        private static final CommParamsModel instance  = new CommParamsModel();
    }
    public static final CommParamsModel instance(){
        return ParamsHolder.instance;
    }

    private String appImei;
    private String appType;
    private String appVersion;

    public void initCommParams(String imei,String type,String version){
        this.appImei = imei;
        this.appType = type;
        this.appVersion = version;
    }

    public String getAppImei() {
        return appImei;
    }

    public String getAppType() {
        return appType;
    }

    public String getAppVersion() {
        return appVersion;
    }
}


//初始化公参,  imei  {apptype 1,android}  appVersion
CommParamsModel.instance().initCommParams(PhoneUtils.getIMEI(),"1", AppInfo.appVersionName());


package com.ruidonghy.zbase.utils;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 捕捉Json解析异常,避免出现由此引起 的crash
 * @author wjian
 * */
public class WillJsonParseUtils
{
	private static Gson gson;
	static {
		gson = new Gson();
	}

	public static Gson getGson()
	{
		return gson;
	}

	/**
	 * 对象转成json
	 * @param <T>
	 */
	public static <T> String obj2JsonStr(T t, String def)
	{
		try 
		{
			return gson.toJson(t);
		} catch (Exception e) {
			e.printStackTrace();
			LogUtils.e("json解析异常"+t,e.getMessage());
		}
		return def;
	}

	/**
	 * json转成对象
	 * 
	 * @param <T>
	 */
	public static <T> T json2Obj(String json, Class<T> clazz)
	{
		try {
			return gson.fromJson(json, clazz);
		} catch (JsonSyntaxException e) {
			e.printStackTrace();
			LogUtils.e("json解析异常"+json,e.getMessage());
		}
		return null;
	}

	/**
	 * json字符串直接转成List
	 * @param clazz  Bean[].class
	 * @param json String json串
	 * @param <T>
     * @return
     */

//	public static final <T> List<T> json2List(final Class<T[]> clazz, final String json)
//	{
//		final T[] jsonToObject;
//		try{
//			 jsonToObject = gson.fromJson(json, clazz);
//		}catch (Exception e){
//			e.printStackTrace();
//			return new ArrayList<T>();
//		}
//		return Arrays.asList(jsonToObject);
//	}

	/**
	 * json字符直接转成json对象
	 */
	public static <T> T json2Object(String jsonString, Class<T> cls) {
		T t = null;
		try {
			Gson gson = new Gson();
			t = gson.fromJson(jsonString, cls);
		} catch (Exception e) {
			e.printStackTrace();
			LogUtils.e("json解析异常"+jsonString,e.getMessage());
		}
		return t;
	}

	public static String getString(JSONObject json, String key)
	{
		return getString(json, key, "");
	}

	public static String getString(JSONObject json, String key, String def)
	{
		String value = def;
		if (canParse(json, key)) {
			try {
				value = json.getString(key);
			} catch (JSONException e) {
				LogUtils.e("getString=" + e.getMessage());
				LogUtils.e("json解析异常"+json,e.getMessage());
			}
		}

		return value;
	}	
	
	public static int getInt(JSONObject json, String key)
	{
		return getInt(json, key, -1);
	}

	public static int getInt(JSONObject json, String key, int def)
	{
		int value = def;
		if (canParse(json, key)) {
			try {
				value = json.getInt(key);
			} catch (JSONException e) {
				LogUtils.e("getInt=" + e.getMessage());
			}
		}

		return value;
	}
	
	public static long getLong(JSONObject json, String key)
	{
		return getLong(json, key, -1);
	}
	
	public static long getLong(JSONObject json, String key, long def)
	{
		long value = def;
		if (canParse(json, key)) {
			try {
				value = json.getLong(key);
			} catch (JSONException e) {
				LogUtils.e("getInt=" + e.getMessage());
			}
		}

		return value;
	}
	
	public static JSONObject getJSONObject(JSONArray array, int index)
	{
		return getJSONObject(array, index, new JSONObject());
	}
	
	public static JSONObject getJSONObject(JSONArray array, int index, JSONObject def)
	{
		JSONObject returnObj = def;
		if (array != null && array.length() > 0) {
			try {
				returnObj = array.getJSONObject(index);
			} catch (JSONException e) {
				LogUtils.e("getJSONObject=" + e.getMessage());
			}
		}
		return returnObj;
	}
	
	public static JSONObject getJSONObject(JSONObject json, String key)
	{
		return getJSONObject(json, key, new JSONObject());
	}

	public static JSONObject getJSONObject(JSONObject json, String key, JSONObject def)
	{
		JSONObject returnObj = def;
		if (canParse(json, key)) {
			try {
				returnObj = json.getJSONObject(key);
			} catch (JSONException e) {
				LogUtils.e("getJSONObject=" + e.getMessage());
			}
		}
		return returnObj;
	}
	
	public static JSONArray getJSONArray(JSONObject json, String key)
	{
		return getJSONArray(json, key, new JSONArray());
	}

	public static JSONArray getJSONArray(JSONObject json, String key, JSONArray def)
	{
		JSONArray array = def;
		if (canParse(json, key)) {
			try {
				array = json.getJSONArray(key);
			} catch (JSONException e) {
				LogUtils.e("getJSONArray=" + e.getMessage());
			}
		}
		return array;
	}
	
	public static JSONObject getJSONObject(byte[] json)
	{
		return getJSONObject(StringUtils.bytesToString(json,"UTF-8"));
	}

	public static JSONObject getJSONObject(String json)
	{
		return getJSONObject(json, new JSONObject());
	}
	
	public static JSONObject getJSONObject(String json, JSONObject def)
	{
		JSONObject jsonObject = def;
		try {
			jsonObject = new JSONObject(json);
		} catch (Exception e) {  //不只是JsonException,还可能是别的异常
			e.printStackTrace();
		}
		return jsonObject;
	}
	
	public static JSONArray getJSONArray(String json)
	{
		return getJSONArray(json, new JSONArray());
	}
	
	public static JSONArray getJSONArray(String json, JSONArray def)
	{
		JSONArray jsonArray = def;
		try {
			jsonArray = new JSONArray(json);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return jsonArray;
	}

	/**
	 * 判断数据是否可以解析,可以则return true;
	 * */
	private static boolean canParse(JSONObject json, String key)
	{
		if (json == null || TextUtils.isEmpty(key)) {
			return false;
		}
		return true;
	}

	public static <T> List<T> parseJsonArray2List(JSONArray jsonArray, Class<T> clazz)
	{
		List<T> list = new ArrayList<T>();
		if(jsonArray==null) return list;
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject jsonObject = getJSONObject(jsonArray, i, null);
			if(jsonObject==null) continue;
			T t = (T) json2Obj(jsonObject.toString(),clazz);
			list.add(t);
		}
		return list;
	}
	
	public static List<Integer> parseJsonArray2IntegerList(JSONArray jsonArray)
	{
		List<Integer> list = new ArrayList<Integer>();
		if(jsonArray==null) return list;
		for (int i = 0; i < jsonArray.length(); i++) {
			int anInt = 0;
			try {
				anInt = jsonArray.getInt(i);
			} catch (JSONException e) {
				e.printStackTrace();
			}
			list.add(anInt);
		}
		return list;
	}

	public static void putValue(JSONObject json, String key, Object value)
	{
		try {
			json.put(key,value);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	public static Map<String, Object> jsonToMap(String jsonString) throws JSONException {
		JSONObject jsonObject = new JSONObject(jsonString);
		Map<String, Object> resultMap = new HashMap<String, Object>();
		Iterator<String> iter = jsonObject.keys();
		String key=null;
		Object value=null;
		while (iter.hasNext()) {
			key=iter.next();
			value=jsonObject.get(key);
			resultMap.put(key, value);
		}
		return resultMap;
	}

	public static Map<String, String> json2Map(String jsonString) throws JSONException {
		JSONObject jsonObject = new JSONObject(jsonString);
		Map<String, String> resultMap = new HashMap<String, String>();
		Iterator<String> iter = jsonObject.keys();
		String key=null;
		String value=null;
		while (iter.hasNext()) {
			key=iter.next();
			value=jsonObject.get(key).toString();
			resultMap.put(key, value);
		}
		return resultMap;
	}

	/**
	 * map转json
	 *
	 * @param map
	 * @return
	 * @throws JSONException
	 */
	public static String map2Json(Map<String, String> map) throws JSONException {
		Gson gson = new Gson();
		String jsonStr = gson.toJson(map);
		return jsonStr;
	}
}



package com.ruidonghy.zbase.utils;

import java.util.Random;

/**
 * Created by zhou on 2017/11/8 11:32.
 */
public class RandomUtil {
    public static Random random = new Random();

    public RandomUtil() {
    }

    public static String getRandom(int length) {
        StringBuilder ret = new StringBuilder();

        for(int i = 0; i < length; ++i) {
            boolean isChar = random.nextInt(2) % 2 == 0;
            if(isChar) {
                int choice = random.nextInt(2) % 2 == 0?65:97;
                ret.append((char)(choice + random.nextInt(26)));
            } else {
                ret.append(Integer.toString(random.nextInt(10)));
            }
        }

        return ret.toString();
    }
}



package com.ruidonghy.zbase.utils;

import android.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES加解密
 * Created by zhou on 2017/11/8 11:22.
 */
public class AESUtils {

    /**
     * 密钥算法
     */
    private static final String ALGORITHM = "AES";
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String ALGORITHM_STR = "AES/CBC/PKCS5Padding";

    //AES加密初始向量
    public static final String VIPARA = "w2wJCnctEG09danPPI7SxQ==";   //AES 为16bytes. DES 为8byte

    /**
     * SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范
     */
    private SecretKeySpec key;

    public AESUtils(String hexKey) {
        key = new SecretKeySpec(hexKey.getBytes(), ALGORITHM);
    }

    /**
     * AES加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public String encryptData(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
        IvParameterSpec zeroIv = new IvParameterSpec(Base64.decode(VIPARA,Base64.DEFAULT));
        cipher.init(Cipher.ENCRYPT_MODE, key,zeroIv);// 初始化
        return new String(Base64.encode(cipher.doFinal(data.getBytes("UTF-8")),Base64.DEFAULT),"UTF-8");
    }

    /**
     * AES解密
     *
     * @return
     * @throws Exception
     */
//    public String decryptData(String base64Data) throws Exception {
//        Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
//        cipher.init(Cipher.DECRYPT_MODE, key);
//        return StringUtils.bytesToString(cipher.doFinal(Base64Utils.getFromBase64(base64Data).getBytes("UTF-8")),"UTF-8");
//    }

//    /**
//     * hex字符串 转 byte数组
//     *
//     * @param s
//     * @return
//     */
//    private static byte[] hex2byte(String s) {
//        if (s.length() % 2 == 0) {
//            return hex2byte(s.getBytes(), 0, s.length() >> 1);
//        } else {
//            return hex2byte("0" + s);
//        }
//    }
//
//    private static byte[] hex2byte(byte[] b, int offset, int len) {
//        byte[] d = new byte[len];
//        for (int i = 0; i < len * 2; i++) {
//            int shift = i % 2 == 1 ? 0 : 4;
//            d[i >> 1] |= Character.digit((char) b[offset + i], 16) << shift;
//        }
//        return d;
//    }

//    public static void main(String[] args) throws Exception {
//        AESUtils util = new AESUtils("abcdefghijklmnop"); // 密钥
//        System.out.println("cardNo:" + util.encryptData("1234")); // 加密
//        System.out.println("exp:" + util.decryptData("34+Jzs4KkwaCQWVyyAgwLA==")); // 解密
//    }

    public static String encodeAES(String json,String aesKey) throws Exception {
        AESUtils aes = new AESUtils(aesKey);
        return aes.encryptData(json);
    }

}



package com.ruidonghy.zbase.utils;

import android.util.Base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

/**
 * Created by zhou on 2017/11/10 18:50 .
 */

public class RsaUtils {
    private static final String RSA_PUBLICE =
            "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHrouGyrJsGZLqNiLtAvpOlPpe" +
                    "UxmQdpfHSvIMqi7kHCe01VeHDFaB2wpOm9Fk2ExNELHd0BNjX7i3esvD319dJpia" +
                    "qnXpkVesTNAnXj4+KPhUFu0Je26VpTfvBx6PSKrWrGOXPGt0S6BnIFjDL5tXxYsk" +
                    "RZ2/2jdJMt/YjSnk2wIDAQAB";
    private static final String ALGORITHM = "RSA";

    /**
     * 得到公钥
     * @param algorithm
     * @param bysKey
     * @return
     */
    private static PublicKey getPublicKeyFromX509(String algorithm,
                                                  String bysKey) throws NoSuchAlgorithmException, Exception {
        byte[] decodedKey = Base64.decode(bysKey,Base64.DEFAULT);
        X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodedKey);

        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        return keyFactory.generatePublic(x509);
    }

    /**
     * 使用公钥加密
     * @param content
     * @return
     */
    public static String encryptByPublic(String content) {
        try {
            PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, pubkey);

            byte plaintext[] = content.getBytes("UTF-8");
            byte[] output = cipher.doFinal(plaintext);

            String s = new String(Base64.encode(output,Base64.DEFAULT));

            return s;

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 使用公钥解密
     * @param content 密文
     * @return 解密后的字符串
     */
    public static String decryptByPublic(String content) {
        try {
            PublicKey pubkey = getPublicKeyFromX509(ALGORITHM, RSA_PUBLICE);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, pubkey);
            InputStream ins = new ByteArrayInputStream(Base64.decode(content,Base64.DEFAULT));
            ByteArrayOutputStream writer = new ByteArrayOutputStream();
            byte[] buf = new byte[128];
            int bufl;
            while ((bufl = ins.read(buf)) != -1) {
                byte[] block = null;
                if (buf.length == bufl) {
                    block = buf;
                } else {
                    block = new byte[bufl];
                    for (int i = 0; i < bufl; i++) {
                        block[i] = buf[i];
                    }
                }
                writer.write(cipher.doFinal(block));
            }
            return new String(writer.toByteArray(), "UTF-8");
        } catch (Exception e) {
            return null;
        }
    }
}

复制代码

ServerErrorUtil

说明:

package com.ruidonghy.zbase.net;

import android.widget.Toast;

import com.ruidonghy.zbase.base.BaseApplication;
import com.ruidonghy.zbase.base.BaseResult;
import com.ruidonghy.zbase.utils.LogUtils;

/**
 * Created by zhou on 2017/11/13 14:22 .
 *
 * 公共服务器错误雏形类,目前没有指定的需要拦截的错误码类型,日后会加
 *
 */

public class ServerErrorUtil {
    public static boolean isSuccess(BaseResult baseResult,boolean isShowErrorMsg){
        if (baseResult.code==200){//返回200则请求成功,服务器正常给返回数据
            if(baseResult.result==null){//服务器返回200结果Result数据是null,,则 1,log日志在控制台提示  2,返回false,让上层去做处理
                LogUtils.e("服务器返回Result为null,请联系服务器人员!");
                return false;
            }
            return true;
        }else{
/**
 200  => 'SUCCESS',
 500  => '服务器内部错误',
 4101 => '添加数据失败',
 4201 => '请求校验失败',
 4202 => 'loginkey无效',
 4203 => '缺少参数',
 4204 => '参数错误',
 4205 => '验证码错误',
 4206 => '注册失败',
 4207 => '验证码获取失败',
 4208 => '验证码获取频繁',
 4209 => '绑定失败',
 4210 => '已在其他设备登录',
 */

            //拦截指定错误码  目前还未有指定
            switch(baseResult.code){
                case 500://服务器内部错误
                    ;break;
                case 4101://添加数据失败
                    ;break;
                case 4201://请求校验失败
                    ;break;
                case 4202://loginkey无效
                    ;break;
                case 4203://缺少参数
                    ;break;
                case 4204://参数错误
                    ;break;
                case 4205://验证码错误
                    ;break;
                case 4206://注册失败
                    ;break;
                case 4207://验证码获取失败
                    ;break;
                case 4208://验证码获取频繁
                    ;break;
                case 4209://绑定失败
                    ;break;
                case 4210://已在其他设备登录
                    ;break;
                case 4221://评论自己错误
                    ;break;
            }

            //如果上层需要显示错误信息的话,则用固定的Toast来show错误消息
            if (isShowErrorMsg){
                Toast.makeText(BaseApplication.instance(),baseResult.message,Toast.LENGTH_LONG).show();
            }
            return false;
        }

    }
}



package com.ruidonghy.zbase.net;

import java.net.ConnectException;
import java.net.UnknownHostException;

import retrofit2.HttpException;


/**
 * Created by abbott on 2017/12/8.
 */

public class ExceptionUtil {
    public static final int SERVER_ERROR = 9000;//服务器异常
    public static final int HTTP_ERROR = 9001;//网络异常

    public static int errorCode(Throwable e) {
        if (e instanceof HttpException || e instanceof UnknownHostException || e instanceof ConnectException) {
            return HTTP_ERROR;
        } else {
            return SERVER_ERROR;
        }
    }

}


package com.ruidonghy.zbase.net;

/**
 * Created by zhou on 2017/11/6 16:48 .
 */

public class URLConfig {
    public static final String HOST_ONLINE = "http://api.xxx.com/";//线上环境
    public static final String HOST_PRE_ONLINE = "http://api.xxx.com/";//预上线环境
    public static final String HOST_TEST = "http://api.xxx.com/";//测试环境
    public static final String HOST_DEV = "http://api.xxx.com/";//开发环境

    public static final int URL_TYPE = 3;//1是线上 2是预上线 3是测试 4是研发环境,自己随便配置的

    public static String getHost() {
        String host = "";
        switch (URL_TYPE) {
            case 1:
                host = HOST_ONLINE;
                break;
            case 2:
                host = HOST_PRE_ONLINE;
                break;
            case 3:
                host = HOST_TEST;
                break;
            case 4:
                host = HOST_DEV;
                break;
            default:
                host = HOST_ONLINE;
                break;
        }
        return host;
    }


    public static String JD_IMAGE_ENDSTR_MID = "?imgalias/img_mid";//?imgalias/img_mid
    public static String JD_IMAGE_ENDSTR_SMALL = "?imgalias/img_small";//?imgalias/img_small

}


package com.ruidonghy.zbase.net;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;

/**
 * Created by zhou on 2017/11/11 17:56 .
 */

public abstract class CallBack<T> implements Observer<T> {
    @Override
    public void onSubscribe(Disposable d) {
    }

    @Override
    public void onNext(T value) {
        onSuccess(value);
    }

    @Override
    public void onError(Throwable e) {
       switch (ExceptionUtil.errorCode(e)){
           case ExceptionUtil.SERVER_ERROR:
               onServerError();
               break;
           case ExceptionUtil.HTTP_ERROR:
               onHttpError();
               break;
       }
        onFail(e);
    }

    @Override
    public void onComplete() {}

    public abstract void onSuccess(T data);

    public abstract void onFail(Throwable e);

    public void onServerError() {}

    public void onHttpError() {}
}

复制代码

StartIndoorRunActivity

说明:

package com.ruidonghy.zbase.data;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by zhou on 2017/11/27 10:23 .
 */

public class StartIndoorRunActivity implements Parcelable {
    public static final String ACTION = "com.ruidonghy.run.indoor.IndoorRunActivity";

    /**
     * 0:为设置距离和时间
     * 1:设置了距离
     * 2:设置了时间
     */
    private int type;
    /**
     * 设定的距离,单位:公里
     */
    private float distance;
    /**
     * 设定的时间,单位:秒
     */
    private long time;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.type);
        dest.writeFloat(this.distance);
        dest.writeLong(this.time);
    }

    public StartIndoorRunActivity(int type, float distance, long time) {
        this.type = type;
        this.distance = distance;
        this.time = time;
    }

    protected StartIndoorRunActivity(Parcel in) {
        this.type = in.readInt();
        this.distance = in.readFloat();
        this.time = in.readLong();
    }

    public static final Parcelable.Creator<StartIndoorRunActivity> CREATOR = new Parcelable.Creator<StartIndoorRunActivity>() {
        @Override
        public StartIndoorRunActivity createFromParcel(Parcel source) {
            return new StartIndoorRunActivity(source);
        }

        @Override
        public StartIndoorRunActivity[] newArray(int size) {
            return new StartIndoorRunActivity[size];
        }
    };

    public int getType() {
        return type;
    }

    public float getDistance() {
        return distance;
    }

    public long getTime() {
        return time;
    }
}

复制代码

转载于:https://juejin.im/post/5b5160eee51d451964624e2b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值