✈️一些封装的工具类:

最近:

好久没更新过CSDN了,在忙一些东西。每天的生活感觉枯燥又无趣哦,每天早上8.00左右来实验室,中午吃饭,下午吃饭,晚上10.00再回寝室,我像被程序控制着的一样,机械的行尸。每天雷打不动的两小时算法,复习计网和操作系统,再看看安卓的源码,再补补java的一些知识,倒是也蛮充足的。

闲言碎语

努努力拼一把吧,做好该做的事情,并接受它的事与愿违。但行好事莫问前程。

不说闲话了,写项目整理了不少工具类,今天就整理一下,以后用起来方便。

1️⃣ 提示框管理类:

提示框管理类里边实现了自定义提示框的显示,隐藏,初始化等。

代码:

/**
 * FileName: DialogManager
 * Profile: 提示框管理类
 */
public class DialogManager {

    private static volatile DialogManager mInstance = null;

    private DialogManager() {

    }

    public static DialogManager getInstance() {
        if (mInstance == null) {
            synchronized (DialogManager.class) {
                if (mInstance == null) {
                    mInstance = new DialogManager();
                }
            }
        }
        return mInstance;
    }

    public DialogView initView(Context mContext, int layout) {
        return new DialogView(mContext, layout, R.style.Theme_Dialog, Gravity.CENTER);
    }

    public DialogView initView(Context mContext, int layout, int gravity) {
        return new DialogView(mContext, layout, R.style.Theme_Dialog, gravity);
    }

    public void show(DialogView view) {
        if (view != null) {
            if (!view.isShowing()) {
                view.show();
            }
        }
    }

    public void hide(DialogView view) {
        if (view != null) {
            if (view.isShowing()) {
                view.dismiss();
            }

        }
    }
}

自定义提示框:

/**
 * FileName: DialogView
 * Profile: 自定义提示框
 */
public class DialogView extends Dialog {

    public DialogView(Context mContext, int layout, int style, int gravity) {
        super(mContext, style);
        setContentView(layout);
        Window window = getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.gravity = gravity;
        window.setAttributes(layoutParams);
    }
}

使用:

  1. 实例化自定义提示框;
  2. 通过提示框管理类将其初始化;
  3. 根据个人逻辑实现显示隐藏。

伪代码:

1.   private DialogView mNullDialogView;     //声明自定义提示框;
//通过管理类提供的方法将其实例化;
2.    mNullDialogView = DialogManager.getInstance().initView(getActivity(), R.layout.layout_star_null_item, Gravity.BOTTOM);
//根据你所需的逻辑来控制其显示和隐藏
3.   DialogManager.getInstance().show(mNullDialogView);

2️⃣网络框架OKHttp管理类:

代码:

/**
 * @author 韩世凯
 * @create 2021.8.10
 * 对OKHttp网络框架进行了封装,使用起来比较方便
 */

public class Api {
    private static OkHttpClient client;
    private static String requestUrl;
    private static HashMap<String, Object> mParams;
    public static Api api = new Api();

    public Api() {

    }

    /*get请求拼接参数*/
    public static Api config(String url, HashMap<String, Object> params) {
        client = new OkHttpClient.Builder()
                .build();
        requestUrl = ApiConfig.BASE_URl + url;
        mParams = params;
        return api;
    }


    public void postRequest(Context context, final ITCallback callback) {
        SharedPreferences sp = context.getSharedPreferences("sp_it", MODE_PRIVATE);
        String token = sp.getString("token", "");
        JSONObject jsonObject = new JSONObject(mParams);
        String jsonStr = jsonObject.toString();
        RequestBody requestBodyJson =
                RequestBody.create(MediaType.parse("application/json;charset=utf-8")
                        , jsonStr);
        //第三步创建Rquest
        Request request = new Request.Builder()
                .url(requestUrl)
                .addHeader("contentType", "application/json;charset=UTF-8")
                .addHeader("token", token)
                .post(requestBodyJson)
                .build();
        //第四步创建call回调对象
        final Call call = client.newCall(request);
        //第五步发起请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("onFailure", e.getMessage());
                callback.onFailure(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                callback.onSuccess(result);
            }
        });
    }

    public void getRequest(Context context, final ITCallback callback) {
        SharedPreferences sp = context.getSharedPreferences("sp_it", MODE_PRIVATE);
        String token = sp.getString("token", "");
        String url = getAppendUrl(requestUrl, mParams);
        Request request = new Request.Builder()
                .url(url)
                .addHeader("token", token)
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("onFailure", e.getMessage());
                callback.onFailure(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String code = jsonObject.getString("code");
                    if (code.equals("401")) {
                        Intent in = new Intent(context, LoginActivity.class);
                        context.startActivity(in);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                callback.onSuccess(result);
            }
        });
    }

    public void getRequestNew(Context context, final ITCallback callback) {
        SharedPreferences sp = context.getSharedPreferences("sp_it", MODE_PRIVATE);
        String token = sp.getString("token", "");
        String url = "http://122.9.144.12:8080/record/api/trainingRecordDetail/"+mParams.get("recordId");
        Request request = new Request.Builder()
                .url(url)
                .addHeader("token", token)
                .get()
                .build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("onFailure", e.getMessage());
                callback.onFailure(e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String result = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String code = jsonObject.getString("code");
                    if (code.equals("401")) {
                        Intent in = new Intent(context, LoginActivity.class);
                        context.startActivity(in);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                callback.onSuccess(result);
            }
        });
    }

    /*拼接参数,返回正确的URL*/
    private String getAppendUrl(String url, Map<String, Object> map) {
        if (map != null && !map.isEmpty()) {
            StringBuffer buffer = new StringBuffer();
            Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                if (StringUtils.isEmpty(buffer.toString())) {
                    buffer.append("?");
                } else {
                    buffer.append("&");
                }
                buffer.append(entry.getKey()).append("=").append(entry.getValue());
            }
            url += buffer.toString();
        }
        return url;
    }
}

和这个管理类配合使用的还需要实现一个接口:

public interface ITCallback {
    void onSuccess(String res);

    void onFailure(Exception e);
}

使用:

这里举我项目中获取记录界面数据的一个请求函数:

/*获取记录界面的数据展示*/
    public void getHFRecordList(final boolean isRefresh) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("pageSize", ApiConfig.LISTSIZE);
        params.put("pageNum", listNum);
        Api.config(ApiConfig.HFRECORDLIST, params).postRequest(getActivity(), new ITCallback() {
            @Override
            public void onSuccess(final String res) {
                if (isRefresh) {
                    refreshLayout.finishRefresh(true);
                } else {
                    refreshLayout.finishLoadMore(true);
                }
                HFRecordShowResponse response = new Gson().fromJson(res, HFRecordShowResponse.class);
                if (response != null && response.getMeta().getCode() == HttpURLConnection.HTTP_OK) {
                    List<HFChildListResponse> list = response.getData().getRecordList().getList();
                    Log.d(TAG, "List.size---->"+list.size());
                    if (list != null && list.size() > 0) {
                        if (isRefresh) {
                            datas = list;
                        } else {
                            datas.addAll(list);
                        }
                        mHandler.sendEmptyMessage(0);
                    } else {
                        if (isRefresh) {
                            showToastSync("暂时无数据");
                        } else {
                            showToastSync("没有更多数据");
                        }
                    }
                }
            }

            @Override
            public void onFailure(Exception e) {
                if (isRefresh) {
                    refreshLayout.finishRefresh(true);
                } else {
                    refreshLayout.finishLoadMore(true);
                }
            }
        });
    }

3️⃣ 地图管理类:

里边主要是项目里边使用高德地图的一些管理方法:

包括地址转经纬度,经纬度转地址,正反编码,获取静态地图URL等等

代码:

/**
 * FileName: MapManager
 * Profile: 地图管理类
 */
public class MapManager {

    private static volatile MapManager mInstance = null;

    private GeocodeSearch geocodeSearch;

    private OnAddress2PoiGeocodeListener address2poi;
    private OnPoi2AddressGeocodeListener poi2address;

    private MapManager() {

    }

    //单例模式创建实例
    public static MapManager getInstance() {
        if (mInstance == null) {
            synchronized (MapManager.class) {
                if (mInstance == null) {
                    mInstance = new MapManager();
                }
            }
        }
        return mInstance;
    }

    public void initMap(Context mContext) {
        geocodeSearch = new GeocodeSearch(mContext);
        geocodeSearch.setOnGeocodeSearchListener(searchListener);
    }

    private GeocodeSearch.OnGeocodeSearchListener searchListener = new GeocodeSearch.OnGeocodeSearchListener() {
        @Override
        public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
            if (i == AMapException.CODE_AMAP_SUCCESS) {
                if (regeocodeResult != null) {
                    if (poi2address != null) {
                        poi2address.poi2address(regeocodeResult.getRegeocodeAddress()
                                .getFormatAddress());
                    }
                }
            }
        }

        @Override
        public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
            if (i == AMapException.CODE_AMAP_SUCCESS) {
                if (geocodeResult != null) {
                    if (address2poi != null) {
                        if (geocodeResult.getGeocodeAddressList() != null &&
                                geocodeResult.getGeocodeAddressList().size() > 0) {
                            GeocodeAddress address = geocodeResult.getGeocodeAddressList().get(0);
                            address2poi.address2poi(
                                    address.getLatLonPoint().getLatitude(),
                                    address.getLatLonPoint().getLongitude(),
                                    address.getFormatAddress()
                            );
                        }
                    }
                }
            }
        }
    };

    /**
     * 地址转经纬度
     * @param address
     */
    public MapManager address2poi(String address, OnAddress2PoiGeocodeListener listener) {
        this.address2poi = listener;
        GeocodeQuery query = new GeocodeQuery(address, "");
        geocodeSearch.getFromLocationNameAsyn(query);
        return mInstance;
    }

    /**
     * 经纬度转地址
     * @param la
     * @param lo
     */
    public MapManager poi2address(double la, double lo,OnPoi2AddressGeocodeListener listener) {
        this.poi2address = listener;
        RegeocodeQuery query = new RegeocodeQuery(
                new LatLonPoint(la, lo), 3000, GeocodeSearch.AMAP);
        geocodeSearch.getFromLocationAsyn(query);
        return mInstance;
    }

    public interface OnPoi2AddressGeocodeListener {
        void poi2address(String address);
    }

    public interface OnAddress2PoiGeocodeListener {
        void address2poi(double la, double lo, String address);
    }

    /**
     * 获取静态地图Url
     * @param la
     * @param lo
     * @return
     */
    public String getMapUrl(double la, double lo) {
        String url = "https://restapi.amap.com/v3/staticmap?location=" + lo + "," + la +
                "&zoom=17&scale=2&size=150*150&markers=mid,,A:" + lo + ","
                + la + "&key=" + "389bc08b815e3146bfd1e45fd7f47fc5";
        LogUtils.i("url:" + url);
        return url;
    }
}

使用:

MapManager.getInstance().poi2address(la, lo, new MapManager.OnPoi2AddressGeocodeListener() {
                        @Override
                        public void poi2address(String address) {
                            //发送位置消息
                            CloudManager.getInstance().sendLocationMessage(yourUserId, la, lo, address);
                            addLocation(1, la, lo, address);
                        }
                    });

4️⃣ 多媒体管理类:

里边封装了媒体播放的音乐进度,是否在播放,暂停播放等等一些功能。

代码:

/**
 * FileName: MediaPlayerManager
 * Profile: 媒体播放
 */
public class MediaPlayerManager {

    //播放
    public static final int MEDIA_STATUS_PLAY = 0;
    //暂停
    public static final int MEDIA_STATUS_PAUSE = 1;
    //停止
    public static final int MEDIA_STATUS_STOP = 2;

    public int MEDIA_STATUS = MEDIA_STATUS_STOP;

    private MediaPlayer mMediaPlayer;
    private static final int H_PROGRESS = 1000;

    private OnMusicProgressListener musicProgressListener;

    /**
     * 计算歌曲的进度:
     * 1.开始播放的时候就开启循环计算时长
     * 2.将进度计算结果对外抛出
     */
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what) {
                case H_PROGRESS:
                    if (musicProgressListener != null) {
                        //拿到当前时长
                        int currentPosition = getCurrentPosition();
                        int pos = (int) (((float) currentPosition) / ((float) getDuration()) * 100);
                        musicProgressListener.OnProgress(currentPosition, pos);
                        mHandler.sendEmptyMessageDelayed(H_PROGRESS, 1000);
                    }
                    break;
            }
            return false;
        }
    });

    public MediaPlayerManager() {
        mMediaPlayer = new MediaPlayer();
    }

    /**
     * 是否在播放
     *
     * @return
     */
    public boolean isPlaying() {
        return mMediaPlayer.isPlaying();
    }

    /**
     * 开始播放
     *
     * @param path
     */
    public void startPlay(AssetFileDescriptor path) {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(path.getFileDescriptor(),
                    path.getStartOffset(), path.getLength());
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            MEDIA_STATUS = MEDIA_STATUS_PLAY;
            mHandler.sendEmptyMessage(H_PROGRESS);
        } catch (IOException e) {
            LogUtils.e(e.toString());
            e.printStackTrace();
        }
    }

    /**
     * 开始播放
     *
     * @param path
     */
    public void startPlay(String path) {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            MEDIA_STATUS = MEDIA_STATUS_PLAY;
            mHandler.sendEmptyMessage(H_PROGRESS);
        } catch (IOException e) {
            LogUtils.e(e.toString());
            e.printStackTrace();
        }
    }

    /**
     * 暂停播放
     */
    public void pausePlay() {
        if (isPlaying()) {
            mMediaPlayer.pause();
            MEDIA_STATUS = MEDIA_STATUS_PAUSE;
            removeHandler();
        }
    }

    /**
     * 继续播放
     */
    public void continuePlay() {
        mMediaPlayer.start();
        MEDIA_STATUS = MEDIA_STATUS_PLAY;
        mHandler.sendEmptyMessage(H_PROGRESS);
    }

    /**
     * 停止播放
     */
    public void stopPlay() {
        mMediaPlayer.stop();
        MEDIA_STATUS = MEDIA_STATUS_STOP;
        removeHandler();
    }

    /**
     * 获取当前位置
     *
     * @return
     */
    public int getCurrentPosition() {
        return mMediaPlayer.getCurrentPosition();
    }

    /**
     * 获取总时长
     *
     * @return
     */
    public int getDuration() {
        return mMediaPlayer.getDuration();
    }

    /**
     * 是否循环
     *
     * @param isLooping
     */
    public void setLooping(boolean isLooping) {
        mMediaPlayer.setLooping(isLooping);
    }

    /**
     * 跳转位置
     *
     * @param ms
     */
    public void seekTo(int ms) {
        mMediaPlayer.seekTo(ms);
    }

    /**
     * 无歌曲不需要监听进度
     */
    public void removeHandler() {
        if (mHandler != null) {
            mHandler.removeMessages(H_PROGRESS);
        }
    }


    /**
     * 播放结束
     *
     * @param listener
     */
    public void setOnComplteionListener(MediaPlayer.OnCompletionListener listener) {
        mMediaPlayer.setOnCompletionListener(listener);
    }

    /**
     * 播放错误
     *
     * @param listener
     */
    public void setOnErrorListener(MediaPlayer.OnErrorListener listener) {
        mMediaPlayer.setOnErrorListener(listener);
    }

    /**
     * 播放进度
     *
     * @param listener
     */
    public void setOnProgressListener(OnMusicProgressListener listener) {
        musicProgressListener = listener;
    }

    public interface OnMusicProgressListener {
        void OnProgress(int progress, int pos);
    }
}

使用:

@Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.iv_music_switch:
                if(mGuideMusic.MEDIA_STATUS == MediaPlayerManager.MEDIA_STATUS_PAUSE){
                    mAnim.start();
                    mGuideMusic.continuePlay();
                    iv_music_switch.setImageResource(R.drawable.img_guide_music);
                }else if(mGuideMusic.MEDIA_STATUS == MediaPlayerManager.MEDIA_STATUS_PLAY){
                    mAnim.pause();
                    mGuideMusic.pausePlay();
                    iv_music_switch.setImageResource(R.drawable.img_guide_music_off);
                }
                break;
            case R.id.tv_guide_skip:
                startActivity(new Intent(this,LoginActivity.class));
                finish();
                break;
        }
    }

5️⃣ 动画工具类:

**
 * FileName: AnimUtils
 * Profile: 动画工具类
 */
public class AnimUtils {

    /**
     * 旋转动画
     * @param view
     * @return
     */
    public static ObjectAnimator rotation(View view) {
        ObjectAnimator mAnim = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f);
        mAnim.setDuration(2 * 1000);
        mAnim.setRepeatMode(ValueAnimator.RESTART);
        mAnim.setRepeatCount(ValueAnimator.INFINITE);
        mAnim.setInterpolator(new LinearInterpolator());
        return mAnim;
    }

}

6️⃣ 语言工具类:

/**
 * FileName: LanguaueUtils
 * Profile: 语言工具类
 */
public class LanguaueUtils {

    public static int SYS_LANGUAGE = 0;

    /**
     * 更新系统语言
     * @param mContext
     */
    public static void updateLanguaue(Context mContext) {
        Resources resources = mContext.getResources();
        DisplayMetrics dm = resources.getDisplayMetrics();
        Configuration config = resources.getConfiguration();
        //读取配置
        int languaue = SpUtils.getInstance().getInt(Constants.SP_LANGUAUE, 0);
        SYS_LANGUAGE = languaue;
        if (languaue == 0) {
            config.locale = Locale.SIMPLIFIED_CHINESE;
        } else if (languaue == 1) {
            config.locale = Locale.ENGLISH;
        } else {
            config.locale = Locale.SIMPLIFIED_CHINESE;
        }
        resources.updateConfiguration(config, dm);
    }
}

7️⃣ 日志管理类:

/**
 * FileName: LogUtils
 * Profile: Log
 * <p>
 * Log不光作为日志的打印,还可以记录日志 ——> File
 */
public class LogUtils {

    private static SimpleDateFormat mSimpleDateFormat =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static void i(String text) {
        if (BuildConfig.DEBUG) {
            if (!TextUtils.isEmpty(text)) {
                Log.i(BuildConfig.BUILD_TYPE, text);
                //writeToFile(text);
            }
        }
    }

    public static void e(String text) {
        if (BuildConfig.DEBUG) {
            if (!TextUtils.isEmpty(text)) {
                Log.e(BuildConfig.BUILD_TYPE, text);
                //writeToFile(text);
            }
        }
    }

    /**
     * 写入内存卡
     *
     * @param text
     */
    public static void writeToFile(String text) {
        //开始写入
        FileOutputStream fileOutputStream = null;
        BufferedWriter bufferedWriter = null;
        try {
            //文件路径
            String fileRoot = Environment.getExternalStorageDirectory().getPath() + "/Meet/";
            String fileName = "Meet.log";
            // 时间 + 内容
            String log = mSimpleDateFormat.format(new Date()) + " " + text + "\n";
            //检查父路径
            File fileGroup = new File(fileRoot);
            //创建根布局
            if (!fileGroup.exists()) {
                fileGroup.mkdirs();
            }
            //创建文件
            File fileChild = new File(fileRoot + fileName);
            if (!fileChild.exists()) {
                fileChild.createNewFile();
            }
            fileOutputStream = new FileOutputStream(fileRoot + fileName, true);
            //编码问题 GBK 正确的存入中文
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, Charset.forName("gbk")));
            bufferedWriter.write(log);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            e(e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            e(e.toString());
        } finally {
            if (bufferedWriter != null) {
                try {
                    bufferedWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

8️⃣ SP工具类:

/**
 * FileName: SpUtils
 * Profile:
 */
public class SpUtils {

    private SharedPreferences sp;
    private SharedPreferences.Editor editor;

    /**
     * key - values 存储方式
     * 它的存储路径:data/data/packageName/shared_prefs/sp_name.xml
     * <p>
     * File存储:/sdcard/ 读写方式不一样
     * 数据库:LitePal
     * get/post:数据的读写
     */

    private volatile static SpUtils mInstance = null;

    private SpUtils() {

    }

    public static SpUtils getInstance() {
        if (mInstance == null) {
            synchronized (SpUtils.class) {
                if (mInstance == null) {
                    mInstance = new SpUtils();
                }
            }
        }
        return mInstance;
    }

    public void initSp(Context mContext) {

        /**
         * MODE_PRIVATE:只限于本应用读写
         * MODE_WORLD_READABLE:支持其他应用读,但是不能写
         * MODE_WORLD_WRITEABLE:其他应用可以写
         */
        sp = mContext.getSharedPreferences(BuildConfig.SP_NAME, Context.MODE_PRIVATE);
        editor = sp.edit();
    }

    public void putInt(String key, int values) {
        editor.putInt(key, values);
        editor.commit();
    }

    public int getInt(String key, int defValues) {
        return sp.getInt(key, defValues);
    }

    public void putString(String key, String values) {
        editor.putString(key, values);
        editor.commit();
    }

    public String getString(String key, String defValues) {
        return sp.getString(key, defValues);
    }

    public void putBoolean(String key, boolean values) {
        editor.putBoolean(key, values);
        editor.commit();
    }

    public boolean getBoolean(String key, boolean defValues) {
        return sp.getBoolean(key, defValues);
    }

    public void deleteKey(String key) {
        editor.remove(key);
        editor.commit();
    }

}

9️⃣ 沉浸式UI:

/**
 * FileName: SystemUI
 * Profile: 沉浸式实现
 */
public class SystemUI {

    public static void fixSystemUI(Activity mActivity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //获取最顶层的View
            mActivity.getWindow().getDecorView()
                    .setSystemUiVisibility(
                            View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            mActivity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    }
}

🔟 时间戳转换类:

/**
 * FileName: TimeUtils
 * Profile: 时间转换类
 * 转换时间戳
 */
public class TimeUtils {

    /**
     * 转换毫秒格式 HH:mm:ss
     * 1s = 1000ms
     * 1m = 60s
     * 1h = 60m
     * 1d = 24h
     *
     * @param ms 单位毫秒
     */
    public static String formatDuring(long ms) {
        long hours = ((ms + 28800000) % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
        long minutes = (ms % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (ms % (1000 * 60)) / 1000;

        String h = hours + "";
        if (hours < 10) {
            h = "0" + h;
        }

        String m = minutes + "";
        if (minutes < 10) {
            m = "0" + m;
        }

        String s = seconds + "";
        if (seconds < 10) {
            s = "0" + s;
        }

        return h + ":" + m + ":" + s;
    }

}

⛳️万能的适配器和viewholder:

适配器:

/**
 * FileName: CommonAdapter
 * Profile: 万能的适配器
 */
public class CommonAdapter<T> extends RecyclerView.Adapter<CommonViewHolder> {

    private List<T> mList;

    private OnBindDataListener<T> onBindDataListener;
    private OnMoreBindDataListener<T> onMoreBindDataListener;

    public CommonAdapter(List<T> mList, OnBindDataListener<T> onBindDataListener) {
        this.mList = mList;
        this.onBindDataListener = onBindDataListener;
    }

    public CommonAdapter(List<T> mList, OnMoreBindDataListener<T> onMoreBindDataListener) {
        this.mList = mList;
        this.onBindDataListener = onMoreBindDataListener;
        this.onMoreBindDataListener = onMoreBindDataListener;
    }

    //绑定数据
    public interface OnBindDataListener<T> {
        void onBindViewHolder(T model, CommonViewHolder viewHolder, int type, int position);
        int getLayoutId(int type);
    }

    //绑定多类型的数据
    public interface OnMoreBindDataListener<T> extends OnBindDataListener<T> {
        int getItemType(int position);
    }

    @Override
    public int getItemViewType(int position) {
        if (onMoreBindDataListener != null) {
            return onMoreBindDataListener.getItemType(position);
        }
        return 0;
    }

    @Override
    public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        int layoutId = onBindDataListener.getLayoutId(viewType);
        CommonViewHolder viewHolder = CommonViewHolder.getViewHolder(parent, layoutId);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(CommonViewHolder holder, int position) {
        onBindDataListener.onBindViewHolder(
                mList.get(position), holder, getItemViewType(position), position);
    }

    @Override
    public int getItemCount() {
        return mList == null ? 0 : mList.size();
    }
}

万能的viewholder:

/**
 * FileName: CommonViewHolder
 * Profile: 万能的ViewHolder
 */
public class CommonViewHolder extends RecyclerView.ViewHolder {

    //子View的集合
    private SparseArray<View> mViews;
    private View mContentView;

    public CommonViewHolder(View itemView) {
        super(itemView);
        mViews = new SparseArray<>();
        mContentView = itemView;
    }

    /**
     * 获取CommonViewHolder实体
     *
     * @param parent
     * @param layoutId
     * @return
     */
    public static CommonViewHolder getViewHolder(ViewGroup parent, int layoutId) {
        return new CommonViewHolder(View.inflate(parent.getContext(), layoutId, null));
    }

    /**
     * 提供给外部访问View的方法
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View> T getView(int viewId) {
        View view = mViews.get(viewId);
        if (view == null) {
            view = mContentView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }

    /**
     * 设置文本
     *
     * @param viewId
     * @param text
     * @return
     */
    public CommonViewHolder setText(int viewId, String text) {
        TextView tv = getView(viewId);
        tv.setText(text);
        return this;
    }

    /**
     * 设置图片链接
     *
     * @param mContext
     * @param viewId
     * @param url
     * @return
     */
    public CommonViewHolder setImageUrl(Context mContext, int viewId, String url) {
        ImageView iv = getView(viewId);
        GlideHelper.loadUrl(mContext, url, iv);
        return this;
    }

    /**
     * 压缩
     *
     * @param mContext
     * @param viewId
     * @param url
     * @param w
     * @param h
     * @return
     */
    public CommonViewHolder setImageUrl(Context mContext, int viewId, String url, int w, int h) {
        ImageView iv = getView(viewId);
        GlideHelper.loadSmollUrl(mContext, url, w, h, iv);
        return this;
    }


    /**
     * 设置图片文件
     *
     * @param mContext
     * @param viewId
     * @param file
     * @return
     */
    public CommonViewHolder setImageFile(Context mContext, int viewId, File file) {
        ImageView iv = getView(viewId);
        GlideHelper.loadFile(mContext, file, iv);
        return this;
    }

    /**
     * 设置图片
     *
     * @param viewId
     * @param resId
     * @return
     */
    public CommonViewHolder setImageResource(int viewId, int resId) {
        ImageView iv = getView(viewId);
        iv.setImageResource(resId);
        return this;
    }

    /**
     * 设置背景颜色
     *
     * @param viewId
     * @param color
     * @return
     */
    public CommonViewHolder setBackgroundColor(int viewId, int color) {
        ImageView iv = getView(viewId);
        iv.setBackgroundColor(color);
        return this;
    }

    /**
     * 设置文本颜色
     *
     * @param viewId
     * @param color
     * @return
     */
    public CommonViewHolder setTextColor(int viewId, int color) {
        TextView tv = getView(viewId);
        tv.setTextColor(color);
        return this;
    }


    /**
     * 设置控件的显示隐藏
     *
     * @param viewId
     * @param visibility
     * @return
     */
    public CommonViewHolder setVisibility(int viewId, int visibility) {
        TextView tv = getView(viewId);
        tv.setVisibility(visibility);
        return this;
    }
}

简单使用:

mAllFriendView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mAllFriendView.addItemDecoration(new DividerItemDecoration(getActivity(),
                DividerItemDecoration.VERTICAL));
        mAllFriendAdapter = new CommonAdapter<>(mList, new CommonAdapter.OnBindDataListener<AllFriendModel>() {
            @Override
            public void onBindViewHolder(final AllFriendModel model, CommonViewHolder viewHolder, int type, int position) {
                viewHolder.setImageUrl(getActivity(), R.id.iv_photo, model.getUrl());
                viewHolder.setText(R.id.tv_nickname, model.getNickName());
                viewHolder.setImageResource(R.id.iv_sex, model.isSex()
                        ? R.drawable.img_boy_icon : R.drawable.img_girl_icon);
                viewHolder.setText(R.id.tv_desc, model.getDesc());

                viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        UserInfoActivity.startActivity(getActivity(),model.getUserId());
                    }
                });
            }

            @Override
            public int getLayoutId(int type) {
                return R.layout.layout_all_friend_item;
            }
        });
        mAllFriendView.setAdapter(mAllFriendAdapter);

使用方式就和普通的适配器一样,看上面的例子就好了。