IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android开发复用代码 -> 正文阅读

[移动开发]Android开发复用代码

1.设置状态栏透明

    if (Build.VERSION.SDK_INT >= 21){
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
            int ui = decorView.getSystemUiVisibility();
            ui |=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; //设置状态栏中字体的颜色为白色
            decorView.setSystemUiVisibility(ui);
        }
if (Build.VERSION.SDK_INT >= 21){
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            getWindow().setStatusBarColor(Color.BLACK);
            int ui = decorView.getSystemUiVisibility();
            ui |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; //设置状态栏中字体的颜色为黑色
            decorView.setSystemUiVisibility(ui);
        }

2.Dialog样式一(是/否)

private void showNormalDialog(final String xid){
        final AlertDialog.Builder normalDialog =
                new AlertDialog.Builder(alldata.this);
        normalDialog.setTitle("删除");
        normalDialog.setMessage("确认是否删除?");
        normalDialog.setPositiveButton("确定",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        del(xid);
                    }
                });
        normalDialog.setNegativeButton("关闭",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(alldata.this, "关闭", Toast.LENGTH_SHORT).show();
                    }
                });
        // 显示
        normalDialog.show();
    }

2.1 Dialog样式二(新手引导)

private void newYingdao() {
        LayoutInflater inflater = LayoutInflater.from(courseInfo.this);
        View view = inflater.inflate(R.layout.tips1, null);
        AlertDialog.Builder builder=new AlertDialog.Builder(courseInfo.this,R.style.TransparentDialog);
        builder.setView(view);
        final AlertDialog dialog=builder.create();
        final Button b=view.findViewById(R.id.button4);
        final LinearLayout tips=view.findViewById(R.id.tips);
        tips.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialog.show();

    }
<style name="TransparentDialog" parent="Theme.AppCompat.Dialog">
        <item name="android:windowBackground">@color/transparent</item>
    </style>

2.2 Diaglog点击其他地方不销毁

 //创建dialog
                final AlertDialog dialog=builder.create();
                //dialog点击其他地方不关闭
                dialog.setCancelable(false);

3.从下方弹出页面

 private void dialogs2() {
        LayoutInflater inflater = LayoutInflater.from(getApplication());
        View view = inflater.inflate(R.layout.home_ulist, null);
        AlertDialog.Builder builder=new AlertDialog.Builder(home.this);
        builder.setView(view);
        final AlertDialog dialog=builder.create();
        Window window = dialog.getWindow();
        final TextView bianji=view.findViewById(R.id.bianji);
        users(bianji);
        window.setGravity(Gravity.BOTTOM);  //此处可以设置dialog显示的位置
        window.setWindowAnimations(R.style.SelectUpload2);  //添加动画
        dialog.show();
        WindowManager.LayoutParams params =
                dialog.getWindow().getAttributes();
        WindowManager wm = (WindowManager)home.this.getSystemService(Context.WINDOW_SERVICE);
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        dialog.getWindow().setBackgroundDrawableResource(R.color.white);
        dialog.getWindow().setAttributes(params);
    }
<style name="SelectUpload2">

        <item name="android:windowEnterAnimation">@anim/dialog_enter</item>  //进入时的动画
        <item name="android:windowExitAnimation">@anim/dialog_exit</item>    //退出时的动

    </style>

4.封装的PrefStore

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class PrefStore {

    private static final String STORE_NAME = "Settings";
    private static Context mContext = null;
    private static PrefStore instance = null;

    public static PrefStore getInstance(Context context) {
        if (instance == null) {
            instance = new PrefStore(context);
        }
        return instance;
    }

    public PrefStore(Context context) {
        mContext = context.getApplicationContext();
    }

    public boolean savePref(String key, String value) {

        if (mContext != null) {
            SharedPreferences pref = mContext.getSharedPreferences(STORE_NAME,
                    Context.MODE_PRIVATE);
            Editor editor = pref.edit();
            editor.putString(key, value);
            editor.commit();
            return true;
        } else {
            return false;
        }

    }

    public String getPref(String key, String defValue) {

        if (mContext != null) {
            SharedPreferences pref = mContext.getSharedPreferences(STORE_NAME,
                    Context.MODE_PRIVATE);
            return pref.getString(key, defValue);
        } else {
            return null;
        }

    }

    public boolean removePref(String key) {
        if (mContext != null) {
            SharedPreferences pref = mContext.getSharedPreferences(STORE_NAME,
                    Context.MODE_PRIVATE);
            Editor editor = pref.edit();
            editor.remove(key);
            editor.commit();
            return true;
        } else {
            return false;
        }
    }

    public boolean clearPref() {
        if (mContext != null) {
            SharedPreferences pref = mContext.getSharedPreferences(STORE_NAME,
                    Context.MODE_MULTI_PROCESS);
            Editor editor = pref.edit();
            editor.clear();
            editor.commit();
            return true;
        } else {
            return false;
        }
    }

}

4.1 封装的PrefStore使用

PrefStore pref = PrefStore.getInstance(Login.this);
pref.savePref("Phone", USERS.getPhone());
pref.getPref("Uid","1")

5.封装的PicassoUtils

PicassoUtils.loadImageViewCrop2(ChangeHeadImage.this,localhost_path+ result, imageView);

6.封装的OkHttpUtils

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

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

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * OkHttp的封装工具类
 */
public class OkHttpUtils {
    //TAG
    private static final String TAG = OkHttpUtils.class.getSimpleName();
    //声明客户端
    private OkHttpClient client;
    //防止多个线程同时访问所造成的安全隐患
    private volatile static OkHttpUtils okHttpUtils;
    //定义提交类型Json
    private static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");
    //定义提交类型String
    private static final MediaType STRING = MediaType.parse("text/x-markdown;charset=utf-8");
    //子线程
    private Handler handler;
    //构造方法
    private OkHttpUtils() {
        //初始化
        client = new OkHttpClient();
        handler = new Handler(Looper.getMainLooper());
    }
    //单例模式
    public static OkHttpUtils getInstance() {
//        OkHttpUtils okUtils = null;
//        if (okHttpUtils == null) {
//            //线程同步
//            synchronized (OkHttpUtils.class) {
//                if (okUtils == null) {
//                    okUtils = new OkHttpUtils();
//                    okHttpUtils = okUtils;
//                }
//            }
//        }
        OkHttpUtils okUtils = new OkHttpUtils();
        return okUtils;
    }
    /**
     * 请求的返回结果是json字符串
     * @param jsonValue
     * @param callBack
     */
    private void onsuccessJsonStringMethod(final String jsonValue, final FuncJsonString callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        //解析json
                        callBack.onResponse(jsonValue);
                    } catch (Exception e) {

                    }
                }
            }
        });
    }
    /**
     * 求的返回结果是json对象
     * @param jsonValue
     * @param callBack
     */
    private void onsuccessJsonObjectMethod(final String jsonValue, final FuncJsonObject callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        callBack.onResponse(new JSONObject(jsonValue));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    /**
     * 求的返回结果是json数组
     * @param data
     * @param callBack
     */
    private void onsuccessJsonByteMethod(final byte[] data, final FuncJsonObjectByte callBack) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onResponse(data);
                }
            }
        });
    }
    /**
     * 同步请求,不是很常用,因为会阻塞线程
     * @param url
     * @return
     */
    public String syncGetByURL(String url) {
        //构建一个Request请求
        Request request = new Request.Builder().url(url).build();
        Response response = null;
        try {
            //同步请求数据
            response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 请求指定的url,返回的结果是json字符串
     *
     * @param url
     * @param callback
     */
    public void syncJsonStringByURL(String url, final FuncJsonString callback) {
        final Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }

            //解析成功
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonStringMethod(response.body().string(), callback);
                }
            }
        });
    }


    /**
     * 请求指定的url,返回的结果是json对象
     *
     * @param url
     * @param callback
     */
    public void syscJsonObjectByURL(String url, final FuncJsonObject callback) {
        final Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");



            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonObjectMethod(response.body().string(), callback);
                }
            }
        });
    }
    /**
     * 请求指定的url,返回的结果是byte字节数组
     *
     * @param url
     * @param callback
     */
    public void syscGetByteByURL(String url, final FuncJsonObjectByte callback) {
        final Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonByteMethod(response.body().bytes(), callback);
                }
            }
        });
    }

    /**
     * 请求指定的url,返回的结果是Bitmap
     * @param url
     * @param callback
     */
    public void syscDownloadImageByURL(String url, final FuncJsonObjectBitmap callback) {
        final Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    byte[] data = response.body().bytes();
                    Bitmap bitmap = new PicassoUtils.CropImageView().transform(BitmapFactory.decodeByteArray(data, 0, data.length));
                    callback.onResponse(bitmap);
                }
            }
        });
    }
    /**
     * 向服务器提交表单
     * @param url      提交地址
     * @param params   提交数据
     * @param callback 提交回调
     */
    public void sendDatafForClicent(String url, Map<String, String> params, final FuncJsonObject callback) {
        //表单对象,包含input开始的操作
        FormBody.Builder from = new FormBody.Builder();
        //键值对不为空,他的值也不为空
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                //装载表单值
                from.add(entry.getKey(), entry.getValue());
            }
        }
        RequestBody body = from.build();
        //post提交
        Request request = new Request.Builder().url(url).post(body).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonObjectMethod(response.body().string(), callback);
                }
            }
        });
    }

    //todo post请求带参数
    public void sendDatafForClicent2(String url, Map<String, String> params, final FuncJsonString callback) {
        //表单对象,包含input开始的操作
        FormBody.Builder from = new FormBody.Builder();
        //键值对不为空,他的值也不为空
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                //装载表单值
                from.add(entry.getKey(), entry.getValue());
            }
        }
        RequestBody body = from.build();
        //post提交
        Request request = new Request.Builder().url(url).post(body).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }
            //解析成功
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonStringMethod(response.body().string(), callback);
                }
            }
        });
    }
    //todo post请求带参数
    public void sendDatafForClicent3(String url, Map<String, String> params, final FuncJsonString callback) {
        //表单对象,包含input开始的操作
        FormBody.Builder from = new FormBody.Builder();
        //键值对不为空,他的值也不为空
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                //装载表单值
                from.add(entry.getKey(), entry.getValue());
            }
        }
        RequestBody body = from.build();
        //post提交
        Request request = new Request.Builder().url(url).post(body).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }
            //解析成功
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonStringMethod(response.body().string(), callback);
                }
            }
        });
    }
    //todo 无参数Post请求
    public void sendPostNoParams(String url, final FuncJsonString callback) {
        //表单对象,包含input开始的操作
        FormBody.Builder from = new FormBody.Builder();
        RequestBody body = from.build();
        //post提交
        Request request = new Request.Builder().url(url).post(body).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i(TAG, "解析失败");
            }
            //解析成功
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()) {
                    onsuccessJsonStringMethod(response.body().string(), callback);
                }
            }
        });
    }
    /**
     * 返回字符串json的接口
     */
    public interface FuncJsonString {
        //处理我们返回的结果
        void onResponse(String result);
    }
    /**
     * 返回json对象的接口
     */
    public interface FuncJsonObject {
        //处理我们返回的结果
        void onResponse(JSONObject jsonObject);
    }
    /**
     * 返回json对象的接口
     */
    interface FuncJsonObjectByte {
        //处理我们返回的结果
        void onResponse(byte[] result);
    }
    /**
     * 返回json对象的接口
     */
    interface FuncJsonObjectBitmap {
        //处理我们返回的结果
        void onResponse(Bitmap bitmap);
    }
}


6.1 封装的OkHttpUtils发送 Post请求

	//todo post请求
    private void Post(){
        blogInfos.clear();
        Map<String,String> hs=new HashMap<>();
        hs.put("uname", String.valueOf("admin-all"));
        OkHttpUtils okHttp = OkHttpUtils.getInstance();
        okHttp.sendDatafForClicent2(getAllXiangList,hs, new OkHttpUtils.FuncJsonString() {
            @Override
            public void onResponse(String result) {
                JsonParser parser = new JsonParser();
                JsonArray jsonArray = parser.parse(result).getAsJsonArray();
                Gson gson = new Gson();
                PrefStore pref = PrefStore.getInstance(mydata.this);
                for (JsonElement Title : jsonArray) {
                    Xiangzi g= gson.fromJson(Title, Xiangzi.class);
                    if(g.getUserid()==Integer.valueOf(pref.getPref("Uid","1"))){
                        blogInfos.add(g);
                    }

                }
                initListView();
            }
        });

    }

7.简单适配器

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.example.sushe.R;
import com.example.sushe.model.Xiangzi;
import com.example.sushe.url.url;
import com.example.sushe.utils.OkHttpUtils;
import com.example.sushe.utils.PrefStore;

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


public class ListAdapter extends BaseAdapter {
    private List<Xiangzi> mList;
    private Context mContext;
    public ListAdapter(Context mContext, List<Xiangzi> mList) {
        this.mContext=mContext;
        this.mList=mList;
    }

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

    @Override
    public Object getItem(int position) {
        return mList!=null?mList.get(position):null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.bloglist_item, parent, false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        final ViewHolder finalHolder = holder;
       

        return convertView;
    }
    

    private class ViewHolder{
        LinearLayout root;
        public ViewHolder(View view) {
            if(view==null)
                return;
            root= view.findViewById(R.id.root);
            
        }
    }
}

8.抖音的简单实现

implementation 'com.shuyu:GSYVideoPlayer:5.0.2'
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.sushe.R;
import com.shuyu.gsyvideoplayer.GSYVideoManager;
import com.shuyu.gsyvideoplayer.utils.OrientationUtils;
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;

import java.util.ArrayList;

import static com.example.sushe.url.url.localhost_path;


public class MainActivity extends AppCompatActivity {
    private static final String TAG = "--------------->";
    private RecyclerView mRecyclerView;
    private MyAdapter mAdapter;
    MyLayoutManager myLayoutManager;
    private OrientationUtils orientationUtils;
    private ArrayList<String> ls = new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dys);
//        if (Build.VERSION.SDK_INT >= 21){
//            View decorView = getWindow().getDecorView();
//            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
//            getWindow().setStatusBarColor(Color.TRANSPARENT);
//            int ui = decorView.getSystemUiVisibility();
//            ui |=View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; //设置状态栏中字体的颜色为黑色
//            decorView.setSystemUiVisibility(ui);
//        }

        ls.add(localhost_path+"/vedio/mm1.mp4");
        ls.add(localhost_path+"/vedio/mm5.mp4");
        ls.add(localhost_path+"/vedio/mm3.mp4");
        ls.add(localhost_path+"/vedio/mm1.mp4");
        ls.add(localhost_path+"/vedio/mm5.mp4");
        ls.add(localhost_path+"/vedio/mm3.mp4");
        initView();
        initListener();
    }
    private void initView() {
        mRecyclerView = findViewById(R.id.recycler);
        myLayoutManager = new MyLayoutManager(this, OrientationHelper.VERTICAL,false);

        mAdapter = new MyAdapter();
        mRecyclerView.setLayoutManager(myLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
    }

    private void initListener(){
        myLayoutManager.setOnViewPagerListener(new OnViewPagerListener() {
            @Override
            public void onInitComplete() {

            }

            @Override
            public void onPageRelease(boolean isNext, int position) {
                Log.e(TAG,"释放位置:"+position +" 下一页:"+isNext);
                Toast.makeText(MainActivity.this,"23", Toast.LENGTH_SHORT).show();
                releaseVideo(position);
            }

            @Override
            public void onPageSelected(int position, boolean isNext) {
                Log.e(TAG,"释放位置:"+position +" 下一页:"+isNext);
                Toast.makeText(MainActivity.this,"23", Toast.LENGTH_SHORT).show();
                playVideo(position);
            }
        });
    }

    class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
             public MyAdapter(){
        }
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_pager,parent,false);

            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.t.setVisibility(View.GONE);
//            Toast.makeText(MainActivity.this,"23",Toast.LENGTH_SHORT).show();
            //增加封面
            ImageView imageView = new ImageView(MainActivity.this);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
           // imageView.setImageResource(R.drawable.p10);
            holder.videoPlayer.setThumbImageView(imageView);
            //增加title
            holder.videoPlayer.getTitleTextView().setVisibility(View.VISIBLE);
            //设置返回键
            holder.videoPlayer.getBackButton().setVisibility(View.VISIBLE);
            //设置旋转
            orientationUtils = new OrientationUtils(MainActivity.this, holder.videoPlayer);
            //设置全屏按键功能,这是使用的是选择屏幕,而不是全屏
            holder.videoPlayer.getFullscreenButton().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    orientationUtils.resolveByClick();
                }
            });
            //是否可以滑动调整
            holder.videoPlayer.setIsTouchWiget(true);
            //设置返回按键功能
            holder.videoPlayer.getBackButton().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
            holder.videoPlayer.startPlayLogic();
        }

        @Override
        public int getItemCount() {
            return 15;
        }

        public class ViewHolder extends RecyclerView.ViewHolder{

            StandardGSYVideoPlayer videoPlayer;
            LinearLayout z1;
            TextView t;

            public ViewHolder(View itemView) {
                super(itemView);
                videoPlayer = itemView.findViewById(R.id.video_view);
                z1=itemView.findViewById(R.id.z1);
                t=itemView.findViewById(R.id.textView16);
            }

        }
    }

    private void releaseVideo(int index){
        View itemView = mRecyclerView.getChildAt(index);
        final StandardGSYVideoPlayer videoPlayer = itemView.findViewById(R.id.video_view);
        videoPlayer.onVideoPause();
    }


    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    private void playVideo(int position) {
        View itemView = mRecyclerView.getChildAt(0);
        final StandardGSYVideoPlayer videoPlayer = itemView.findViewById(R.id.video_view);
        final TextView z1=itemView.findViewById(R.id.textView16);
      //  z1.setText("223");
        videoPlayer.startPlayLogic();

    }




    @Override
    protected void onDestroy() {
        super.onDestroy();
        GSYVideoManager.releaseAllVideos();
        if (orientationUtils != null) {
            orientationUtils.releaseListener();
        }
    }

}
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PagerSnapHelper;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class MyLayoutManager extends LinearLayoutManager implements RecyclerView.OnChildAttachStateChangeListener {
    //位移,用来判断移动方向
    private int mDrift;

    private PagerSnapHelper mPagerSnapHelper;
    private OnViewPagerListener mOnViewPagerListener;

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

    public MyLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        mPagerSnapHelper = new PagerSnapHelper();
    }

    @Override
    public void onAttachedToWindow(RecyclerView view) {

        view.addOnChildAttachStateChangeListener(this);
        mPagerSnapHelper.attachToRecyclerView(view);
        super.onAttachedToWindow(view);
    }

    /**
     * 当Item添加进来了  调用这个方法
     * 播放视频操作 即将要播放的是上一个视频 还是下一个视频
     * @param view
     */
    @Override
    public void onChildViewAttachedToWindow(@NonNull View view) {
        if (mDrift > 0) {
//            向上
            if (mOnViewPagerListener != null) {
                mOnViewPagerListener.onPageSelected(getPosition(view), true);
            }

        } else {
            if (mOnViewPagerListener != null) {
                mOnViewPagerListener.onPageSelected(getPosition(view), false);
            }
        }
    }

    public void setOnViewPagerListener(OnViewPagerListener mOnViewPagerListener) {
        this.mOnViewPagerListener = mOnViewPagerListener;
    }

    /**
     * OnScrollListener.SCROLL_STATE_FLING; //屏幕处于甩动状态
     * OnScrollListener.SCROLL_STATE_IDLE; //停止滑动状态
     * OnScrollListener.SCROLL_STATE_TOUCH_SCROLL;// 手指接触状态
     *
     * @param state
     */
    @Override
    public void onScrollStateChanged(int state) {
        switch (state) {
            case RecyclerView.SCROLL_STATE_IDLE:
                View view = mPagerSnapHelper.findSnapView(this);
                int position = getPosition(view);
                if (mOnViewPagerListener != null) {
                    mOnViewPagerListener.onPageSelected(position, position == getItemCount() - 1);

                }


                break;
            default:
        }
        super.onScrollStateChanged(state);
    }

    /**
     * 暂停播放操作
     * @param view
     */
    @Override
    public void onChildViewDetachedFromWindow(@NonNull View view) {
       // sflag=1;
        if (mDrift >= 0) {
            if (mOnViewPagerListener != null) {
          //      mOnViewPagerListener.onPageRelease(true, getPosition(view));
            }
        } else {
            if (mOnViewPagerListener != null) {
         //       mOnViewPagerListener.onPageRelease(false, getPosition(view));
            }
        }
    }


    /**
     * 监听移动方向
     * @param dy
     * @param recycler
     * @param state
     * @return
     */
    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        this.mDrift = dy;
        return super.scrollVerticallyBy(dy, recycler, state);
    }

    @Override
    public boolean canScrollVertically() {
        return true;
    }
}

public interface OnViewPagerListener {
    /**
     * 初始化完成
     */
    void onInitComplete();

    /**
     * 释放的监听
     * @param isNext
     * @param position
     */
    void onPageRelease(boolean isNext, int position);

    /**
     * 选中的监听以及判断是否滑动到底部
     * @param position
     * @param isBottom
     */
    void onPageSelected(int position, boolean isBottom);


}

<?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:id="@+id/root_view"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical">

        <com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
            android:id="@+id/video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="45dp"
                android:gravity="center"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginRight="10dp"
                    android:textSize="19dp"
                    android:textStyle="bold"
                    android:text="学习"
                    android:textColor="#FBF8F8" />

                <TextView
                    android:id="@+id/textView50"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:layout_marginLeft="10dp"
                    android:textSize="19dp"
                    android:text="娱乐"
                    android:textStyle="bold"
                    android:textColor="#FBF8F8" />
            </LinearLayout>
        </com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer>


        <LinearLayout
            android:id="@+id/z1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginTop="-320dp"
            android:layout_marginRight="15dp"
            android:gravity="right"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="left"
                android:orientation="vertical">

                <ImageView
                    android:id="@+id/imageView7"
                    android:layout_width="45dp"
                    android:layout_height="30dp" />

                <TextView
                    android:id="@+id/textView16"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="3dp"
                    android:layout_marginLeft="-5dp"
                    android:gravity="center"
                    android:text=""
                    android:textColor="#ffffff"
                    android:textSize="13.5dp" />

                <ImageView
                    android:id="@+id/imageView8"
                    android:layout_width="37dp"
                    android:layout_height="37dp"
                    android:layout_marginTop="15dp"
                    android:background="@drawable/pls" />

                <TextView
                    android:id="@+id/textView17"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="3dp"
                    android:layout_marginLeft="-5dp"
                    android:gravity="center"
                    android:text=""
                    android:textColor="#ffffff"
                    android:textSize="13.5dp" />

                <ImageView
                    android:id="@+id/imageView10"
                    android:layout_width="37dp"
                    android:layout_height="37dp"
                    android:layout_marginTop="15dp"
                    android:background="@drawable/zhuanfa" />

                <TextView
                    android:id="@+id/textView42"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="3dp"
                    android:layout_marginLeft="-3dp"
                    android:gravity="center"
                    android:text="0"
                    android:textColor="#ffffff"
                    android:textSize="13.5dp" />
            </LinearLayout>

        </LinearLayout>

        <LinearLayout
            android:id="@+id/fs"
            android:layout_width="270dp"
            android:layout_height="100dp"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="-5dp"
            android:orientation="vertical">

                <LinearLayout
                    android:id="@+id/xiazai"
                    android:layout_width="wrap_content"
                    android:layout_height="20dp"
                    android:orientation="horizontal"
                    android:visibility="gone"
                    >
                    <ImageView
                        android:id="@+id/imageView14"
                        android:layout_width="20dp"
                        android:layout_height="20dp"
                        android:background="@drawable/xiazai" />

                    <TextView
                        android:id="@+id/textView68"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:textColor="#ffffff"
                        android:textStyle="bold"
                        android:text="点击下载源码解析" />

                </LinearLayout>




            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="35dp"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/textView43"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text=""
                    android:textStyle="bold"
                    android:textColor="#ffffff"
                    android:textSize="17.5dp" />

                <TextView
                    android:id="@+id/textView44"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:text=" 2020/12/18/ 22:54:01"
                    android:textColor="#EAE4E4"
                    android:textSize="16dp" />
            </LinearLayout>

            <TextView
                android:id="@+id/textView38"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="青春就是用来绽放的"
                android:textColor="#EFEDED"
                android:textSize="16dp" />
        </LinearLayout>

    </LinearLayout>



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#000000"
        android:visibility="gone"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView41"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:layout_marginBottom="15dp"
            android:text="留下你的精彩评论吧"
            android:textSize="17dp"
            android:layout_marginLeft="15dp"
            android:textColor="#ECEBEB" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:layout_marginTop="15dp"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/imageView9"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginRight="15dp"
                android:layout_gravity="right"
                android:layout_marginTop="15dp"
                android:background="@drawable/xiaolian" />
        </LinearLayout>
    </LinearLayout>


</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<com.example.amusic.love.Love_dy xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/los1"
    android:background="#000000"
    android:layout_width="match_parent"
    android:layout_marginTop="-2dp"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"

        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

    <VideoView
        android:id="@+id/line_bottom"
        android:layout_width="match_parent"
        android:layout_height="1px"

        android:background="#000000" />


</com.example.amusic.love.Love_dy>

9.封装的GsonUtils


import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import java.util.ArrayList;
import java.util.List;

public class GsonUtils {

    private static Gson gson;

    static {
        gson = new Gson();
    }

    public static <T> T jsonToBean(String gsonString, Class<T> cls) {
        T t = null;
        if (gson != null) {
            t = gson.fromJson(gsonString, cls);
        }
        return t;
    }

    public static String beanToJson(Object object) {
        String gsonString = null;
        if (gson != null) {
            gsonString = gson.toJson(object);
        }
        return gsonString;
    }

    /**
     * 王正瑞
     * @date 2021/12/21 23:12
     * 转成list 解决泛型问题
     * @param json json
     * @param cls  类
     * @param <T>  T
     * @return T列表
     */
    public static <T> List<T> jsonGsonToList(String json, Class<T> cls) {
        Gson gson = new Gson();
        List<T> list = new ArrayList<>();
        JsonArray array = new JsonParser().parse(json).getAsJsonArray();
        for (final JsonElement elem : array) {
            list.add(gson.fromJson(elem, cls));
        }
        return list;
    }

}

9.1 GsonUtils使用

blog=GsonUtils.jsonGsonToList(result,blog.class);

10.加载时间

//todo 加载时间
    public static String disposeTime() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DAY_OF_MONTH, 0);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        String time = sdf.format(c.getTime());
        return time;
    }

11.获取屏幕高度/宽度

//todo 获取屏幕高度调用此函数
    public static int getAndroiodScreenHeigh(WindowManager wm) {
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        int height = dm.heightPixels;       // 屏幕高度(像素)
        return height;
    }
    //todo 获取屏幕宽度调用此函数
    public static int getAndroiodScreenWidth(WindowManager wm) {
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;         // 屏幕宽度(像素)
        return width;
    }

12.android简单适配

private void checkState() {
        boolean hasAccessibility = AccessibilityUtil.isSettingOpen(AutoTouchService.class, MainActivity.this);
        boolean hasWinPermission = FloatWinPermissionCompat.getInstance().check(this);
        if (hasAccessibility) {
            if (hasWinPermission) {
                tvStart.setText(STRING_START);
            } else {
                tvStart.setText(STRING_ALERT);
            }
        } else {
            tvStart.setText(STRING_ACCESS);
        }
    }

12.1 悬浮窗权限兼容类

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.util.Log;

import java.lang.reflect.Method;

/**
 * 悬浮窗权限兼容类
 * 参考了该项目的代码:https://github.com/zhaozepeng/FloatWindowPermission
 */
public class FloatWinPermissionCompat {

    private static final String TAG = FloatWinPermissionCompat.class.getSimpleName();

    public static FloatWinPermissionCompat getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private static class SingletonHolder {
        private static final FloatWinPermissionCompat INSTANCE = new FloatWinPermissionCompat();
    }

    private CompatImpl compat;

    private FloatWinPermissionCompat() {
        // 6.0 以下的处理
        if (Build.VERSION.SDK_INT < 23) {
            if (RomUtils.isMiui()) {
                compat = new MiuiCompatImpl();
            } else if (RomUtils.isMeizu()) {
                compat = new MeizuCompatImpl();
            } else if (RomUtils.isHuawei()) {
                compat = new HuaweiCompatImpl();
            } else if (RomUtils.isQihoo()) {
                compat = new QihooCompatImpl();
            } else {
                // Android6.0以下未兼容机型默认实现
                compat = new BelowApi23CompatImpl() {
                    @Override
                    public boolean isSupported() {
                        return false;
                    }

                    @Override
                    public boolean apply(Context context) {
                        return false;
                    }
                };
            }
        } else {
            // 魅族单独适配一下
            if (RomUtils.isMeizu()) {
                compat = new MeizuCompatImpl();
            } else {
                // 6.0 版本之后由于 google 增加了对悬浮窗权限的管理,所以方式就统一了
                compat = new Api23CompatImpl();
            }
        }
    }

    /**
     * 检查是否已开启悬浮窗权限
     *
     * @return
     */
    public boolean check(Context context) {
        return compat.check(context);
    }

    /**
     * 是否支持打开悬浮窗授权界面
     *
     * @return
     */
    public boolean isSupported() {
        return compat.isSupported();
    }


    /**
     * 检测 op 值判断悬浮窗是否已授权
     *
     * @param context
     * @param op
     * @return
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static boolean checkOp(Context context, int op) {
        final int version = Build.VERSION.SDK_INT;
        if (version >= 19) {
            AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            try {
                Class clazz = AppOpsManager.class;
                Method method = clazz.getDeclaredMethod("checkOp", int.class, int.class, String.class);
                return AppOpsManager.MODE_ALLOWED == (int) method.invoke(manager, op, Binder.getCallingUid(), context.getPackageName());
            } catch (Exception e) {
                Log.e(TAG, Log.getStackTraceString(e));
            }
        } else {
            Log.e(TAG, "Below API 19 cannot invoke!");
        }
        return false;
    }


    public interface CompatImpl {
        /**
         * 检测是否已经权限
         *
         * @param context
         * @return
         */
        boolean check(Context context);

        /**
         * 对于该 ROM 是否已经做了悬浮窗授权的兼容支持
         *
         * @return
         */
        boolean isSupported();

        /**
         * 申请权限
         *
         * @param context
         * @return
         */
        boolean apply(Context context);
    }

    /**
     * 申请悬浮窗权限
     *
     * @return 是否成功打开授权界面
     */
    public boolean apply(Context context) {
        if (!isSupported()) {
            return false;
        }
        forResult = false;
        this.context = context;
        return compat.apply(context);
    }

    public boolean apply(Activity activity) {
        if (activity == null || !isSupported()) {
            return false;
        }
        this.activity = activity;
        this.context = activity.getApplicationContext();
        forResult = true;
        return compat.apply(context);
    }

    public static final int REQUEST_CODE_SYSTEM_WINDOW = 1001;
    private Activity activity;
    private Context context;
    private boolean forResult = false;

    public void startActivity(Intent intent) {
        try {
            if (intent == null || context == null) {
                return;
            }
            if (!forResult) {
                context.startActivity(intent);
            } else {
                if (activity != null) {//为什么打开权限设置页就执行了onActivityResult?
                    activity.startActivityForResult(intent, REQUEST_CODE_SYSTEM_WINDOW);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

12.2 华为悬浮窗权限兼容实现

import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * 华为悬浮窗权限兼容实现
 */
public class HuaweiCompatImpl extends BelowApi23CompatImpl {

    private static final String TAG = "HuaweiCompatImpl";

    @Override
    public boolean isSupported() {
        return true;
    }

    @Override
    public boolean apply(Context context) {
        try {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            // ComponentName comp = new ComponentName("com.huawei.systemmanager","com.huawei.permissionmanager.ui.MainActivity");//华为权限管理
            // "com.huawei.permissionmanager.ui.SingleAppActivity");//华为权限管理,跳转到指定app的权限管理位置需要华为接口权限,未解决
            ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.addviewmonitor.AddViewMonitorActivity");//悬浮窗管理页面
            intent.setComponent(comp);
            if (RomUtils.getEmuiVersion() == 3.1) {
                //emui 3.1 的适配
                startActivity(context, intent);
            } else {
                //emui 3.0 的适配
                comp = new ComponentName("com.huawei.systemmanager", "com.huawei.notificationmanager.ui.NotificationManagmentActivity");//悬浮窗管理页面
                intent.setComponent(comp);
                startActivity(context, intent);
            }
        } catch (SecurityException e) {
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            ComponentName comp = new ComponentName("com.huawei.systemmanager",
                    "com.huawei.permissionmanager.ui.MainActivity");//华为权限管理,跳转到本app的权限管理页面,这个需要华为接口权限,未解决
            //ComponentName comp = new ComponentName("com.huawei.systemmanager","com.huawei.systemmanager.addviewmonitor.AddViewMonitorActivity");//悬浮窗管理页面
            intent.setComponent(comp);
            startActivity(context, intent);
            Log.e(TAG, Log.getStackTraceString(e));
        } catch (ActivityNotFoundException e) {
            /**
             * 手机管家版本较低 HUAWEI SC-UL10
             */
            Intent intent = new Intent();
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            ComponentName comp = new ComponentName("com.Android.settings", "com.android.settings.permission.TabItem");//权限管理页面 android4.4
            //ComponentName comp = new ComponentName("com.android.settings","com.android.settings.permission.single_app_activity");//此处可跳转到指定app对应的权限管理页面,但是需要相关权限,未解决
            intent.setComponent(comp);
            startActivity(context, intent);
            Log.e(TAG, Log.getStackTraceString(e));
        } catch (Exception e) {
            //抛出异常时提示信息
            Log.e(TAG, Log.getStackTraceString(e));
        }
        return false;
    }

    private void startActivity(Context context, Intent intent) {
        context.startActivity(intent);
        //FloatWinPermissionCompat.getInstance().startActivity(intent);
    }

}

12.3 魅族悬浮窗权限兼容实现

import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * 魅族悬浮窗权限兼容实现
 */
public class MeizuCompatImpl extends BelowApi23CompatImpl {

    @Override
    public boolean isSupported() {
        return true;
    }

    /**
     * 去魅族权限申请页面
     */
    @Override
    public boolean apply(Context context) {
        try {
            Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
            intent.setClassName("com.meizu.safe", "com.meizu.safe.security.AppSecActivity");
            intent.putExtra("packageName", context.getPackageName());
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(context,intent);
        } catch (Exception e) {
            try {
                Log.d("dq","flyme 6.2.5+,apply permission failed");
                Api23CompatImpl.commonROMPermissionApplyInternal(context);
            } catch (Exception eFinal) {
                eFinal.printStackTrace();
            }
        }
        return true;
    }

    private void startActivity(Context context, Intent intent) {
        context.startActivity(intent);
        //FloatWinPermissionCompat.getInstance().startActivity(intent);
    }

}

12.4 MIUI 悬浮窗权限兼容实现

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.Settings;
import android.util.Log;

/**
 * MIUI 悬浮窗权限兼容实现
 */
public class MiuiCompatImpl extends BelowApi23CompatImpl {

    private static final String TAG = "MiuiCompatImpl";
    private int miuiVersion = -1;

    public MiuiCompatImpl() {
        miuiVersion = RomUtils.getMiuiVersion();
    }

    @Override
    public boolean isSupported() {
        return miuiVersion >= 5 && miuiVersion <= 8;
    }

    @Override
    public boolean apply(Context context) {
        if (miuiVersion == 5) {
            return applyV5(context);
        } else if (miuiVersion == 6) {
            return applyV6(context);
        } else if (miuiVersion == 7) {
            return applyV7(context);
        } else if (miuiVersion == 8) {
            return applyV8(context);
        } else {
            Log.e(TAG, "this is a special MIUI rom version, its version code " + miuiVersion);
        }
        return false;
    }

    /**
     * MIUI8下申请权限
     *
     * @param context
     */
    private boolean applyV8(Context context) {
        Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
        intent.putExtra("extra_pkgname", context.getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context, intent);
            return true;
        }

        intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        intent.setPackage("com.miui.securitycenter");
        intent.putExtra("extra_pkgname", context.getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context, intent);
            return true;
        } else {
            // 小米平板2上没有安全中心,可以打开应用详情页开启权限
            //I/ActivityManager: START u0 {flg=0x14000000 cmp=com.android.settings/.applications.InstalledAppDetailsTop (has extras)}
            return applyV5(context);
        }
    }

    /**
     * MIUI7下申请权限
     *
     * @param context
     */
    private boolean applyV7(Context context) {
        Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
        intent.putExtra("extra_pkgname", context.getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context, intent);
            return true;
        } else {
            Log.e(TAG, "applyV7 Intent is not available!");
        }
        return false;
    }

    /**
     * MIUI6下申请权限
     *
     * @param context
     */
    private boolean applyV6(Context context) {
        Intent intent = new Intent("miui.intent.action.APP_PERM_EDITOR");
        intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
        intent.putExtra("extra_pkgname", context.getPackageName());
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context, intent);
            return true;
        } else {
            Log.e(TAG, "applyV6 Intent is not available!");
        }
        return false;
    }

    /**
     * MIUI5下申请权限
     *
     * @param context
     */
    private boolean applyV5(Context context) {
        Intent intent;
        String packageName = context.getPackageName();
        intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", packageName, null);
        intent.setData(uri);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context, intent);
            return true;
        } else {
            Log.e(TAG, "applyV5 intent is not available!");
        }
        return false;
        //设置页面在应用详情页面
    }

    private void startActivity(Context context, Intent intent) {
        context.startActivity(intent);
        //FloatWinPermissionCompat.getInstance().startActivity(intent);
    }
}

12.5 360 悬浮窗权限兼容实现

import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * 360 悬浮窗权限兼容实现
 */
public class QihooCompatImpl extends BelowApi23CompatImpl {

    private static final String TAG = "QihooCompatImpl";

    @Override
    public boolean isSupported() {
        return true;
    }

    @Override
    public boolean apply(Context context) {
        Intent intent = new Intent();
        intent.setClassName("com.android.settings", "com.android.settings.Settings$OverlaySettingsActivity");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (RomUtils.isIntentAvailable(context, intent)) {
            startActivity(context,intent);
            return true;
        } else {
            intent.setClassName("com.qihoo360.mobilesafe", "com.qihoo360.mobilesafe.ui.index.appEnterActivity");
            if (RomUtils.isIntentAvailable(context, intent)) {
                startActivity(context,intent);
                return true;
            } else {
                Log.e(TAG, "can't open permission page with particular name, please use " +
                        "\"adb shell dumpsys activity\" command and tell me the name of the float window permission page");
            }
        }
        return false;
    }

    private void startActivity(Context context, Intent intent) {
        context.startActivity(intent);
        //FloatWinPermissionCompat.getInstance().startActivity(intent);
    }

}

12.6 Rom 工具类

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Rom 工具类
 */
public class RomUtils {

    private static final String TAG = RomUtils.class.getSimpleName();

    /**
     * 获取 emui 版本号
     *
     * @return
     */
    public static double getEmuiVersion() {
        try {
            String emuiVersion = getSystemProperty("ro.build.version.emui");
            String version = emuiVersion.substring(emuiVersion.indexOf("_") + 1);
            return Double.parseDouble(version);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 4.0;
    }

    /**
     * 获取小米 rom 版本号,获取失败返回 -1
     *
     * @return miui rom version code, if fail , return -1
     */
    public static int getMiuiVersion() {
        String version = getSystemProperty("ro.miui.ui.version.name");
        if (version != null) {
            try {
                return Integer.parseInt(version.substring(1));
            } catch (Exception e) {
                Log.e(TAG, "getInstance miui version code error, version : " + version);
            }
        }
        return -1;
    }

    /**
     * System.getProperties()不返回与 getprop 相同的属性。要获取 getprop 属性,请尝试使用 Runtime.exec() 执行 getprop 并读取其标准输出。
     *
     * @param propName
     * @return
     */
    public static String getSystemProperty(String propName) {
        String line;
        BufferedReader input = null;
        try {
            Process p = Runtime.getRuntime().exec("getprop " + propName);
            input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
            line = input.readLine();
            input.close();
        } catch (IOException ex) {
            Log.e(TAG, "Unable to read sysprop " + propName, ex);
            return null;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    Log.e(TAG, "Exception while closing InputStream", e);
                }
            }
        }
        return line;
    }

    /**
     * 是否OPPO系统
     *
     * @return
     */
    public static boolean isOppo() {
        return !TextUtils.isEmpty(getSystemProperty("ro.build.version.opporom"));
    }

    /**
     * 是否VIVO系统
     *
     * @return
     */
    public static boolean isVivo() {
        return !TextUtils.isEmpty(getSystemProperty("ro.vivo.os.version"));
    }

    /**
     * 是否华为系统
     *
     * @return
     */
    public static boolean isHuawei() {
        return Build.MANUFACTURER.contains("HUAWEI");
    }

    /**
     * 是否小米系统
     *
     * @return
     */
    public static boolean isMiui() {
        return !TextUtils.isEmpty(getSystemProperty("ro.miui.ui.version.name"));
    }

    /**
     * 是否魅族系统
     *
     * @return
     */
    public static boolean isMeizu() {
        String meizuFlymeOSFlag = getSystemProperty("ro.build.display.id");
        return !TextUtils.isEmpty(meizuFlymeOSFlag) && meizuFlymeOSFlag.toLowerCase().contains("flyme");
    }

    /**
     * 是否 360 系统
     *
     * @return
     */
    public static boolean isQihoo() {
        return Build.MANUFACTURER.contains("QiKU");
    }


    /**
     * 判断 Intent 是否有效
     *
     * @param context
     * @param intent
     * @return
     */
    public static boolean isIntentAvailable(Context context, Intent intent) {
        if (intent == null) {
            return false;
        }
        return context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
    }


}

13.击碎爆破粒子

public class ExplosionAnimator extends ValueAnimator {
    public static final int DEFAULT_DURATION = 1500;
    private Particle[][] mParticles;
    private Paint mPaint;
    private View mContainer;

    public ExplosionAnimator(View view, Bitmap bitmap, Rect bound) {

        mPaint = new Paint();
        mContainer = view;

        setFloatValues(0.0f, 1.0f);
        setDuration(DEFAULT_DURATION);

        mParticles = generateParticles(bitmap, bound);
    }

    private Particle[][] generateParticles(Bitmap bitmap, Rect bound) {
        int w = bound.width();
        int h = bound.height();

        int partW_Count = w / Particle.PART_WH; //横向个数
        int partH_Count = h / Particle.PART_WH; //竖向个数

        int bitmap_part_w = bitmap.getWidth() / partW_Count;
        int bitmap_part_h = bitmap.getHeight() / partH_Count;

        Particle[][] particles = new Particle[partH_Count][partW_Count];
        Point point = null;
        for (int row = 0; row < partH_Count; row ++) { //行
            for (int column = 0; column < partW_Count; column ++) { //列
                //取得当前粒子所在位置的颜色
                int color = bitmap.getPixel(column * bitmap_part_w, row * bitmap_part_h);

                point = new Point(column, row); //x是列,y是行

                particles[row][column] = Particle.generateParticle(color, bound, point);
            }
        }

        return particles;
    }

    public void draw(Canvas canvas) {
        if(!isStarted()) { //动画结束时停止
            return;
        }
        for (Particle[] particle : mParticles) {
            for (Particle p : particle) {
                p.advance((Float) getAnimatedValue());
                mPaint.setColor(p.color);
//                mPaint.setAlpha((int) (255 * p.alpha)); //只是这样设置,透明色会显示为黑色
                mPaint.setAlpha((int) (Color.alpha(p.color) * p.alpha)); //这样透明颜色就不是黑色了
                canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);
            }
        }

        mContainer.invalidate();
    }

    @Override
    public void start() {
        super.start();
        mContainer.invalidate();
    }
}
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;

import com.example.amusic.utils.posui.utils.Utils;

import java.util.ArrayList;

public class ExplosionField extends View {
    private static final String TAG = "ExplosionField";
    private static final Canvas mCanvas = new Canvas();
    private ArrayList<ExplosionAnimator> explosionAnimators;
    private OnClickListener onClickListener;

    public ExplosionField(Context context) {
        super(context);
        init();
    }

    public ExplosionField(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        explosionAnimators = new ArrayList<ExplosionAnimator>();

        attach2Activity((Activity) getContext());
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (ExplosionAnimator animator : explosionAnimators) {
            animator.draw(canvas);
        }
    }

    /**
     * 爆破
     * @param view 使得该view爆破
     */
    public void explode(final View view) {
        Rect rect = new Rect();
        view.getGlobalVisibleRect(rect); //得到view相对于整个屏幕的坐标
        rect.offset(0, -Utils.dp2px(25)); //去掉状态栏高度

        final ExplosionAnimator animator = new ExplosionAnimator(this, createBitmapFromView(view), rect);
        explosionAnimators.add(animator);

        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                view.animate().alpha(0f).setDuration(150).start();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                view.animate().alpha(1f).setDuration(150).start();

                //动画结束时从动画集中移除
                explosionAnimators.remove(animation);
                animation = null;
            }
        });
        animator.start();
    }

    private Bitmap createBitmapFromView(View view) {
        /*
         * 为什么屏蔽以下代码段?
         * 如果ImageView直接得到位图,那么当它设置背景(backgroud)时,不会读取到背景颜色
         */
//        if (view instanceof ImageView) {
//            Drawable drawable = ((ImageView)view).getDrawable();
//            if (drawable != null && drawable instanceof BitmapDrawable) {
//                return ((BitmapDrawable) drawable).getBitmap();
//            }
//        }

        //view.clearFocus(); //不同焦点状态显示的可能不同——(azz:不同就不同有什么关系?)

        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);

        if (bitmap != null) {
            synchronized (mCanvas) {
                mCanvas.setBitmap(bitmap);
                view.draw(mCanvas);
                mCanvas.setBitmap(null); //清除引用
            }
        }
        return bitmap;
    }

    /**
     * 给Activity加上全屏覆盖的ExplosionField
     */
    private void attach2Activity(Activity activity) {
        ViewGroup rootView = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);

        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        rootView.addView(this, lp);
    }


    /**
     * 希望谁有破碎效果,就给谁加Listener
     * @param view 可以是ViewGroup
     */
    public void addListener(View view) {
        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            int count = viewGroup.getChildCount();
            for (int i = 0 ; i < count; i++) {
                addListener(viewGroup.getChildAt(i));
            }
        } else {
            view.setClickable(true);
            view.setOnClickListener(getOnClickListener());
        }
    }


    private OnClickListener getOnClickListener() {
        if (null == onClickListener) {

            onClickListener = new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ExplosionField.this.explode(v);

//                view.setOnClickListener(null); // 用过一次就不需要了
                }
            };
        }

        return onClickListener;
    }
}

import android.graphics.Point;
import android.graphics.Rect;

import java.util.Random;

/**
 * 爆破粒子
 */
public class Particle {

    public static final int PART_WH = 8; //默认小球宽高

    //原本的值(不可变)
//    float originCX;
//    float originCY;
//    float originRadius;

    //实际的值(可变)
    float cx; //center x of circle
    float cy; //center y of circle
    float radius;

    int color;
    float alpha;

    static Random random = new Random();

    Rect mBound;

    public static Particle generateParticle(int color, Rect bound, Point point) {
        int row = point.y; //行是高
        int column = point.x; //列是宽

        Particle particle = new Particle();
        particle.mBound = bound;
        particle.color = color;
        particle.alpha = 1f;

        particle.radius = PART_WH;
        particle.cx = bound.left + PART_WH * column;
        particle.cy = bound.top + PART_WH * row;

        return particle;
    }

    public void advance(float factor) {
        cx = cx + factor * random.nextInt(mBound.width()) * (random.nextFloat() - 0.5f);
        cy = cy + factor * random.nextInt(mBound.height() / 2);

        radius = radius - factor * random.nextInt(2);

        alpha = (1f - factor) * (1 + random.nextFloat());
    }
}

import android.content.res.Resources;

public class Utils {
    /**
     * 密度
     */
    public static final float DENSITY = Resources.getSystem().getDisplayMetrics().density;

    public static int dp2px(int dp) {
        return Math.round(dp * DENSITY);
    }
}

13.1 击碎爆破粒子使用

            ExplosionField explosionField = new ExplosionField(mContext);
            explosionField.addListener(view.findViewById(R.id.rootd1));

14.WindowUtils工具类

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import static android.content.Context.WINDOW_SERVICE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

/**
 * 屏幕工具类
 */
public class WindowUtils {

    /**
     * 判断是否是透明背景的Activity
     * @param context
     * @return
     */
    public static boolean isTranslucentOrFloating(Context context){
        boolean isTranslucentOrFloating = false;
        try {
            int [] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = context.obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean)m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }

    /**
     * 修复8.0以上透明背景Activity指定方向时候闪退的bug
     * @param activity
     */
    public static void fixOrientation(Activity activity){
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo)field.get(activity);
            o.screenOrientation = -1;
            field.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取屏幕宽度
     */
    public static int getScreenWidth(Context context){
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    /**
     * 获取屏幕高度
     */
    public static int getScreenHeight(Context context){
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    /**
     * 获取虚拟按键高度
     * @param context
     * @return
     */
    public static int getNavigationBarHeight(Context context) {
        int result = 0;
        if (hasNavBar(context)) {
            Resources res = context.getResources();
            int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = res.getDimensionPixelSize(resourceId);
            }
        }
        return result;
    }

    /**
     * 检查是否存在虚拟按键栏
     * @param context
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static boolean hasNavBar(Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            boolean hasNav = res.getBoolean(resourceId);
            // check override flag
            String sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else { // fallback
            return !ViewConfiguration.get(context).hasPermanentMenuKey();
        }
    }

    /**
     * 判断虚拟按键栏是否重写
     *
     * @return
     */
    private static String getNavBarOverride() {
        String sNavBarOverride = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method m = c.getDeclaredMethod("get", String.class);
                m.setAccessible(true);
                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
            } catch (Throwable e) {
            }
        }
        return sNavBarOverride;
    }

    /**
     * 全屏 - 隐藏状态栏和虚拟按键
     * @param window
     */
    public static void setHideVirtualKey(Window window) {
        //保持布局状态
        int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE|
                //布局位于状态栏下方
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|
                //全屏
                View.SYSTEM_UI_FLAG_FULLSCREEN|
                //隐藏导航栏
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        if (Build.VERSION.SDK_INT >= 19){
            uiOptions |= 0x00001000;
        }else{
            uiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
        }
        window.getDecorView().setSystemUiVisibility(uiOptions);
    }

    /**
     * 改变屏幕亮度
     */
    /**	 * 设置页面的透明度	 * @param bgAlpha 1表示不透明	 */
    public static void setBackgroundAlpha(Activity activity, float bgAlpha) {
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = bgAlpha;
        if (bgAlpha == 1) {
            //不移除该Flag的话,在有视频的页面上的视频会出现黑屏的bug
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

        } else {
            //此行代码主要是解决在华为手机上半透明效果无效的bug
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        }
        activity.getWindow().setAttributes(lp);
    }

    /**
     * 获取状态栏高度
     */
    public static int getStatusBarHeight(Context context) {
        int statusBarHeight = 0;
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = res.getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

    /**
     * 将View全屏
     * @param context
     * @param view
     */
    public static void enterFullScreen(Context context, View view){
        //从原有的View中取出来
        ViewGroup parent = (ViewGroup) view.getParent();
        if (parent != null) {
            parent.removeView(view);
        }

        //找到父布局
        ViewGroup contentView = scanForActivity(context)
                .findViewById(android.R.id.content);

        //添加到父布局中
        ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
                MATCH_PARENT,MATCH_PARENT);
        contentView.addView(view,params);
    }

    /**
     * 将View退出全屏
     */
    public static void exitFullScreen(Context context, View view){
        //找到父布局
        ViewGroup contentView = scanForActivity(context)
                .findViewById(android.R.id.content);
        contentView.removeView(view);
    }

    private static Activity scanForActivity(Context cont) {
        if (cont == null) {
            Log.d("scanForActivity","cont == null");
            return null;
        } else if (cont instanceof Activity) {
            Log.d("scanForActivity","Activity");
            return (Activity) cont;
        } else if (cont instanceof ContextWrapper) {
            Log.d("scanForActivity","ContextWrapper");
            return scanForActivity(((ContextWrapper) cont).getBaseContext());
        }
        Log.d("scanForActivity","not result");
        return null;
    }

    public static WindowManager.LayoutParams newWmParams(int width, int height) {
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_SCALED
                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        if (Build.VERSION.SDK_INT >= 26) {
            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }
        params.width = width;
        params.height = height;
        params.format = PixelFormat.TRANSLUCENT;
        return params;
    }

    public static WindowManager getWindowManager(Context context) {
        return (WindowManager) context.getSystemService(WINDOW_SERVICE);
    }
}

15.常用框架-PhotoView缩放图片

implementation 'com.github.chrisbanes:PhotoView:1.2.6'
 //todo 弹出图片放大缩小
    private void ImaEvent() {
        PhotoView photoView=findViewById(R.id.id_myimg);
        Button xiazai=findViewById(R.id.button13);
        PicassoUtils.loadImageViewCrop2(paihang.this,localhost_path+"/image/lagelangri/paihangpic.png", photoView);

        xiazai.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse(localhost_path+"/image/lagelangri/paihangpic.png");
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(intent);

            }
        });


    }
<uk.co.senab.photoview.PhotoView
        android:id="@+id/id_myimg"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />

16.常用框架-加载gif

implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.7'
<pl.droidsonroids.gif.GifImageView
        android:id="@+id/loading_img"
        android:layout_width="match_parent"
        android:layout_height="450dp"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="80dp"
        android:src="@drawable/wel" />

17.判断App是第一次启动

SharedPreferences setting;
setting = getSharedPreferences(SHARE_APP_TAG, 0);
 private void first() {
        //todo 判断是第一次启动
        Boolean user_first = setting.getBoolean("FIRST21",true);
        if(user_first){//第一次
            setting.edit().putBoolean("FIRST21", false).commit();
            setting.edit().putString("userName", "null").commit();
            setting.edit().putString("passWord", "null").commit();
            setting.edit().putString("devicecode", getPassword()).commit();
            DEVICECODE=setting.getString("devicecode", "");
            Intent intent=new Intent(welcome.this,Login.class);
            startActivity(intent);
        }else{
            //todo 不是第一次启动 自动登录
            uphone=setting.getString("userName", "");
            upassword=setting.getString("passWord", "");
            DEVICECODE=setting.getString("devicecode", "");
            //todo 登陆请求
            newRunner();
            }
    }

18.sqlite数据库

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDatabase extends SQLiteOpenHelper {
    //todo 记录播放历史(上次观看记录)
    public static final String LEARN_HISTORY = "create table Learn(id integer primary key autoincrement,kcid char(20),listid char(20))" ;
    public static final String LOGINUSER = "create table LoginUser(u_id integer,userName char(100),passWord char(20),name char(20),headImage char(100),sex char(20),major char(20),grade char(20),identity char(20),phone char(20),mibao char(20))" ;
    private Context mContext;

    public MyDatabase(Context context, String name, CursorFactory factory,
                      int version) {
        super(context, name, factory, version);
        // TODO Auto-generated constructor stub
        mContext = context ;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL(LEARN_HISTORY);
        db.execSQL(LOGINUSER);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

18.1 简单增删改查

private MyDatabase myDatebaseHelper;
myDatebaseHelper = new MyDatabase(this, SQLITE_NAME, null, 1);
 //todo 检验用户是否登陆过
    public boolean IScheck(String phone) {
        SQLiteDatabase db = myDatebaseHelper.getWritableDatabase();
        String Query = "Select * from LoginUser where phone =?";
        Cursor cursor = db.rawQuery(Query, new String[]{phone});
        if (cursor.getCount() > 0) {
            cursor.close();
            return true;
        }
        cursor.close();
        return false;
    }
    //todo 删除
    public void del(){
        SQLiteDatabase db = myDatebaseHelper.getWritableDatabase();
        db.delete("LoginUser","phone=?",new String[]{USERS.getPhone()});
        db.close();
        addUser();
    }
    //todo  修改
    private void less() {
        SQLiteDatabase db = myDatebaseHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("u_id",USERS.getU_id());
        values.put("userName",USERS.getUserName());
        values.put("passWord", USERS.getPassWord());
        values.put("name", USERS.getName());
        values.put("headImage", USERS.getHeadImage());
        values.put("sex", USERS.getSex());
        values.put("major", USERS.getMajor());
        values.put("grade", USERS.getGrade());
        values.put("identity", USERS.getIdentity());
        values.put("phone", USERS.getPhone());
        values.put("mibao", String.valueOf(USERS.getMibao()));
        db.update("LoginUser",values, "phone=?",new String[]{USERS.getPhone()});
        db.close();
    }
    //todo 添加用户
    private void addUser() {
        SQLiteDatabase db = myDatebaseHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("u_id",USERS.getU_id());
        values.put("userName",USERS.getUserName());
        values.put("passWord", USERS.getPassWord());
        values.put("name", USERS.getName());
        values.put("headImage", USERS.getHeadImage());
        values.put("sex", USERS.getSex());
        values.put("major", USERS.getMajor());
        values.put("grade", USERS.getGrade());
        values.put("identity", USERS.getIdentity());
        values.put("phone", USERS.getPhone());
        values.put("mibao", String.valueOf(USERS.getMibao()));
        db.insert("LoginUser",null, values);
        db.close();
    }

19.流式布局原理

private void addInit() {
        int w,h;
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        w = getAndroiodScreenWidth(wm);
        for(int i=0;i<ls.size();i++){
            final ImageView imageView = new ImageView(this);
            final FrameLayout f=new FrameLayout(this);
            final TextView t=new TextView(this);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(w/5-20,w/5-20);
            t.setGravity(Gravity.CENTER);
            imageView.setAlpha(0.8f);
            t.setTextColor(this.getColor(R.color.ffffff));
            t.setText("未获得");
            for(int j=0;j<ls2.size();j++){
                if(ls.get(i).getHeadImage().equals(ls2.get(j).getHeadImage())){
                   // Toast.makeText(ChangeHeadImage.this,"---"+ls.get(i).getHeadImage()+"---"+ls2.get(i).getHeadImage(),Toast.LENGTH_SHORT).show();
                    imageView.setAlpha(1f);
                    t.setVisibility(View.GONE);
                }
            }
            PicassoUtils.loadImageViewCrop2(ChangeHeadImage.this,localhost_path+ ls.get(i).getHeadImage(), imageView);
            f.addView(imageView);
            f.addView(t);
            gridLayout.addView(f,params);
            //todo 点击已获得的头像 修改头像
            final int finalI = i;
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(imageView.getAlpha()==1f){
                        headImages=ls.get(finalI).getHeadImage();
                        HEADIMA=1;
                        updateUserIma();

                    }else {
                        Toast.makeText(ChangeHeadImage.this,"未获得",Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    }

20.监听屏幕滑动简单原理

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        //继承了Activity的onTouchEvent方法,直接监听点击事件
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            //当手指按下的时候
            x1 = event.getX();
            y1 = event.getY();
        }
        if(event.getAction() == MotionEvent.ACTION_UP) {
            //当手指离开的时候
            x2 = event.getX();
            y2 = event.getY();
            if(y1 - y2 > 50) {
                Toast.makeText(MainActivity.this, "向上滑", Toast.LENGTH_SHORT).show();
            } else if(y2 - y1 > 50) {
                Toast.makeText(MainActivity.this, "向下滑", Toast.LENGTH_SHORT).show();
            } else if(x1 - x2 > 50) {
                Toast.makeText(MainActivity.this, "向左滑", Toast.LENGTH_SHORT).show();
            } else if(x2 - x1 > 50) {
                Toast.makeText(MainActivity.this, "向右滑", Toast.LENGTH_SHORT).show();
            }
        }
        return super.onTouchEvent(event);
    }

21.Listview任意行生成截图分享

 public  static Bitmap createBitmap(ListView listView, Context context){
        int titleHeight,width, height, rootHeight=0;
        Bitmap bitmap;
        Canvas canvas;
        int yPos = 0;
        int listItemNum;
        List<View> childViews = null;
        width = 1200;//宽度等于屏幕宽
        ListAdapter listAdapter = listView.getAdapter();
        listItemNum = listAdapter.getCount();
        childViews = new ArrayList<View>(listItemNum);
        View itemView;
        //计算整体高度:
        if(JTALL==0){
            for(int pos=0; pos < jt.size(); ++pos){
                itemView = listAdapter.getView(jt.get(pos), null, listView);
                //measure过程
                itemView.measure(View.MeasureSpec.makeMeasureSpec(width, View. MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                childViews.add(itemView);
                rootHeight += itemView.getMeasuredHeight();
            }
        }else{
            for(int pos=0; pos < listItemNum; ++pos){
                itemView = listAdapter.getView(pos, null, listView);
                //measure过程
                itemView.measure(View.MeasureSpec.makeMeasureSpec(width, View. MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                childViews.add(itemView);
                rootHeight += itemView.getMeasuredHeight();
            }
            JTALL=0;
        }



        // 创建对应大小的bitmap
        bitmap = Bitmap.createBitmap(width, rootHeight,
                Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);

        Bitmap itemBitmap;
        int childHeight;
        //把每个ItemView生成图片,并画到背景画布上
        for(int pos=0; pos < childViews.size(); ++pos){
            itemView = childViews.get(pos);
            childHeight = itemView.getMeasuredHeight();
            itemBitmap = viewToBitmap(itemView,width,childHeight);
            if(itemBitmap!=null){
                canvas.drawBitmap(itemBitmap, 0, yPos, null);
            }
            yPos = childHeight +yPos;
        }
        canvas.save();
        canvas.restore();

        return bitmap;
    }
    private static Bitmap viewToBitmap(View view, int viewWidth, int viewHeight){
        view.layout(0, 0, viewWidth, viewHeight);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        return bitmap;
    }

21.1 分享

Uri uri = Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), ima, null,null));
private void share(Uri uri){
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_TEXT, "hello world");
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
        shareIntent.setType("image/*");
        startActivity(Intent.createChooser(shareIntent, "activityTitle"));

    }

22.获取当前本地apk的版本/版本号名称

import android.content.Context;
import android.content.pm.PackageManager;

public class APKVersionCodeUtils {
    /**
     * 获取当前本地apk的版本
     *
     * @param mContext
     * @return
     */
    public static int getVersionCode(Context mContext) {
        int versionCode = 0;
        try {
            //获取软件版本号,对应AndroidManifest.xml下android:versionCode
            versionCode = mContext.getPackageManager().
                    getPackageInfo(mContext.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * 获取版本号名称
     *
     * @param context 上下文
     * @return
     */
    public static String getVerName(Context context) {
        String verName = "";
        try {
            verName = context.getPackageManager().
                    getPackageInfo(context.getPackageName(), 0).versionName;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return verName;
    }
}

23.ImageView高度根据图片比例自适应

<ImageView
    android:id="@+id/iv_test"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    />

24.ToastUtil封装类

import android.annotation.SuppressLint;
import android.content.Context;
import android.widget.Toast;

public class ToastUtil {

    @SuppressLint("StaticFieldLeak")
    private static Context mContext;

    public static void init(Context context) {
        mContext = context.getApplicationContext();
    }

    public static void show(String content) {
        Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
    }
}

24.1 ToastUtil封装类使用

ToastUtil.show("23232---3232");

25.Android四大组件-广播入门

25.1 BroadcastReceiver-广播判断网络状态

public class MyNetworkReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        boolean isconnect = false; //判断是否连接网络
        //获取网络连接服务
        ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(context.CONNECTIVITY_SERVICE);
        //判断wifi是否连接
        NetworkInfo.State state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState();
        if (state == NetworkInfo.State.CONNECTED){
            isconnect = true;
            Toast.makeText(context , "wifi连接", Toast.LENGTH_LONG).show();
        }
        //判断GPRS是否连接
        NetworkInfo.State gstate = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
        if (gstate == NetworkInfo.State.CONNECTED){
            isconnect = true;
            Toast.makeText(context , "当前正在使用数据流量", Toast.LENGTH_LONG).show();
        }
        //没网络连接
        if (!isconnect){
            Toast.makeText(context , "无网络连接", Toast.LENGTH_LONG).show();
        }

    }
}

25.2 动态注册广播

 //动态注册广播
        myNetworkReceiver = new MyNetworkReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(myNetworkReceiver, intentFilter);

26.EditText的监听-TextWatcher三个回调

    EditText et = (EditText) findViewById(R.id.et);
    TextWatcher watcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            Log.d(TAG, "beforeTextChanged: s = " + s + ", start = " + start +
                    ", count = " + count + ", after = " + after);
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            Log.d(TAG, "onTextChanged: s = " + s + ", start = " + start +
                    ", before = " + before + ", count = " + count);
        }

        @Override
        public void afterTextChanged(Editable s) {
            Log.d(TAG, "afterTextChanged: " + s);
        }
    };
    et.addTextChangedListener(watcher);

27.Activity+viewPage+Fragment+RadioButton实现左右滑动切换页面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/home15"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bjt"
    tools:context=".fragment.MainActivity">


    <android.support.v4.view.ViewPager
        android:id="@+id/main_ViewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:id="@+id/root1"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:layout_gravity="center"
        android:gravity="center"
        android:visibility="gone"
        android:background="#ffffff"
        android:orientation="vertical">

        <pl.droidsonroids.gif.GifImageView
            android:layout_width="130dp"
            android:layout_height="160dp"
            android:background="@drawable/dtz1" />
    </LinearLayout>
    <RadioGroup
        android:id="@+id/main_tab_RadioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#000000"
        android:alpha="0.9"
        android:orientation="horizontal"
        android:padding="3dp">

        <RadioButton
            android:id="@+id/radio_home"
            android:layout_width="10dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:width="100dp"
            android:height="100dp"
            android:background="@null"
            android:button="@null"
            android:gravity="center"
            android:textStyle="bold"
            android:text="首页"
            android:textColor="#ffffff" />

        <RadioButton
            android:id="@+id/radio_square"
            android:layout_width="10dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:width="100dp"
            android:height="100dp"
            android:background="@null"
            android:button="@null"
            android:gravity="center"
            android:text="短视频"
            android:textStyle="bold"
            android:textColor="#ffffff" />

        <RadioButton
            android:id="@+id/radio_information"
            android:layout_width="10dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:width="100dp"
            android:height="100dp"
            android:background="@null"
            android:button="@null"
            android:gravity="center"
            android:text="学习中心"
            android:textColor="#ffffff"
            android:textStyle="bold" />


        <RadioButton
            android:id="@+id/radio_me"
            android:layout_width="10dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:width="100dp"
            android:height="100dp"
            android:background="@null"
            android:button="@null"
            android:gravity="center"
            android:text="我的"
            android:textStyle="bold"
            android:textColor="#ffffff" />
    </RadioGroup>

</LinearLayout>

public class TwoFragment extends Fragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.activity_login, container, false);
        return view;
    }
}
public class MainActivity extends FragmentActivity implements OnCheckedChangeListener {
    //todo 监听网络变化

    //ViewPager
    private ViewPager main_viewPager;
    //RadioGroup
    private RadioGroup main_tab_RadioGroup;
    //RadioButton
    private RadioButton radio_home, radio_shopcar,
            radio_sort, radio_me, radio_search;
    private ArrayList<Fragment> fragmentList;
    int current = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0)
        {
            finish();
            return;
        }
        //todo  android:background="#F5F6FA"
        setContentView(R.layout.activity_login2);
        // 界面初始函数,用来获取定义的各控件对应的ID
//        //TODO 设置状态栏透明
        if (Build.VERSION.SDK_INT >= 21){
            View decorView = getWindow().getDecorView();
            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
            int ui = decorView.getSystemUiVisibility();
            ui |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; //设置状态栏中字体的颜色为黑色
            decorView.setSystemUiVisibility(ui);
        }

        InitView();
        //todo
        InitViewPager();


    }






    public void InitView() {
        main_tab_RadioGroup = (RadioGroup) findViewById(R.id.main_tab_RadioGroup);
        radio_home = (RadioButton) findViewById(R.id.radio_home);
        radio_shopcar = (RadioButton) findViewById(R.id.radio_square);
        radio_sort = (RadioButton) findViewById(R.id.radio_information);
        radio_me = (RadioButton) findViewById(R.id.radio_me);
        main_tab_RadioGroup.setOnCheckedChangeListener(this);

    }

    public void InitViewPager() {
        main_viewPager = (ViewPager) findViewById(R.id.main_ViewPager);
        fragmentList = new ArrayList<Fragment>();

        //todo 短视频学习
        Fragment learnFragment = new TwoFragment();
        Fragment squareFragment = new SquareFragment();
        Fragment informationFragment = new InformationFragment();
        Fragment meFragment = new MeFragment();
        fragmentList.add(squareFragment);
        fragmentList.add(learnFragment);
        //todo 学习中心
        fragmentList.add(informationFragment);
        fragmentList.add(meFragment);
        main_viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(), fragmentList));
        main_viewPager.setCurrentItem(0);
        main_viewPager.addOnPageChangeListener(new MyListner());


    }

    public class MyAdapter extends FragmentPagerAdapter {
        ArrayList<Fragment> list;
        public MyAdapter(FragmentManager fm, ArrayList<Fragment> list) {
            super(fm);
            this.list = list;
        }

        @Override
        public Fragment getItem(int arg0) {
            return list.get(arg0);
        }
        @Override
        public int getCount() {
            return list.size();
        }
    }

    public class MyListner implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageSelected(int arg0) {
            int current = main_viewPager.getCurrentItem();
            switch (current) {
                case 0:
                    main_tab_RadioGroup.check(R.id.radio_home);
                    break;
                case 1:
                    main_tab_RadioGroup.check(R.id.radio_square);
                    break;
                case 2:
                    main_tab_RadioGroup.check(R.id.radio_information);
                    break;
                case 3:
                    main_tab_RadioGroup.check(R.id.radio_me);
                    break;
            }
        }
    }

    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkId) {

        switch (checkId) {
            case R.id.radio_home:
                current = 0;
                break;
            case R.id.radio_square:
                current = 1;
                break;
            case R.id.radio_information:
                current = 2;
                break;
            case R.id.radio_me:
                current = 3;
                break;
        }
        if (main_viewPager.getCurrentItem() != current) {
            main_viewPager.setCurrentItem(current);
        }
    }





    protected void onStart() {
        super.onStart();

    }
}

28.估值器-贝塞尔曲线-控件封装-抖音点赞特效

import android.animation.TypeEvaluator;
import android.graphics.PointF;

/**
 * 估值器
 * */
public class BasEvaluator implements TypeEvaluator<PointF> {
 
	private PointF p1;
	private PointF p2;
 
	public BasEvaluator(PointF p1, PointF p2) {
		super();
		this.p1 = p1;
		this.p2 = p2;
	}
 
	@Override
	public PointF evaluate(float fraction, PointF p0, PointF p3) {
		// TODO Auto-generated method stub
		PointF pointf = new PointF();
		
		// 贝塞尔曲线公式  p0*(1-t)^3 + 3p1*t*(1-t)^2 + 3p2*t^2*(1-t) + p3^3
		pointf.x = p0.x * (1-fraction) *(1-fraction ) * (1-fraction)
				   +3*p1.x * fraction *(1-fraction )*(1-fraction )
				   +3*p2.x *fraction  *fraction  *(1-fraction )
				   +p3.x*fraction *fraction *fraction ; 
		pointf.y = p0.y * (1-fraction ) *(1-fraction ) * (1-fraction )
				+3*p1.y * fraction *(1-fraction )*(1-fraction )
				+3*p2.y *fraction  *fraction  *(1-fraction )
				+p3.y*fraction *fraction *fraction ; 
		return pointf;
	}
}
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.example.amusic.R;

import java.util.Random;

public class Love_dy extends RelativeLayout {
    private int a2=8;
    private Context context;
    private LayoutParams params;
    private Drawable[] icons = new Drawable[a2];
    private Interpolator[] interpolators = new Interpolator[4];
    private int mWidth;
    private int mHeight;
    private int[] ImaResources={R.drawable.caomei,R.drawable.qiezi,R.drawable.heart_red,R.drawable.xigua,R.drawable.tuzi,R.drawable.tuzi,
            R.drawable.hua,R.drawable.qiezi};
    public Love_dy(Context context, AttributeSet attrs) {
        super(context, attrs);

        this.context = context;
        initView();

    }


    private void initView() {
        for(int i=0;i<a2;i++){
            icons[i] = getResources().getDrawable(ImaResources[i]);
        }
        // 插值器
        interpolators[0] = new AccelerateDecelerateInterpolator(); // 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
        interpolators[1] = new AccelerateInterpolator();  // 在动画开始的地方速率改变比较慢,然后开始加速
        interpolators[2] = new DecelerateInterpolator(); // 在动画开始的地方快然后慢
        interpolators[3] = new LinearInterpolator();  // 以常量速率改变

    }

    public void addLoveView(float x, float y) {
        if (x < 100) {
            x = 101;
        }
        if (y < 100) {
            y = 101;
        }
        mWidth = (int) (x);
        mHeight = (int) (y);
        final ImageView iv = new ImageView(context);

        params = new LayoutParams(200, 200);
        iv.setLayoutParams(params);

        iv.setImageDrawable(icons[new Random().nextInt(a2)]);

        addView(iv);

        // 开启动画,并且用完销毁
        AnimatorSet set = getAnimatorSet(iv);
        set.start();
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // TODO Auto-generated method stub
                super.onAnimationEnd(animation);
                removeView(iv);
            }
        });
    }

    /**
     * 获取动画集合
     *
     * @param iv
     */
    private AnimatorSet getAnimatorSet(ImageView iv) {

        // 1.alpha动画
        ObjectAnimator alpha = ObjectAnimator.ofFloat(iv, "alpha", 0.3f, 1f);

        // 2.缩放动画
        ObjectAnimator scaleX = ObjectAnimator.ofFloat(iv, "scaleX", 0.2f, 1f);
        ObjectAnimator scaleY = ObjectAnimator.ofFloat(iv, "scaleY", 0.2f, 1f);

        // 动画集合
        AnimatorSet set = new AnimatorSet();
        set.playTogether(alpha, scaleX, scaleY);
        set.setDuration(2000);

        // 贝塞尔曲线动画
        ValueAnimator bzier = getBzierAnimator(iv);

        AnimatorSet set2 = new AnimatorSet();
        set2.playTogether(set, bzier);
        set2.setTarget(iv);
        return set2;
    }

    /**
     * 贝塞尔动画
     */
    private ValueAnimator getBzierAnimator(final ImageView iv) {
        // TODO Auto-generated method stub
        PointF[] PointFs = getPointFs(iv); // 4个点的坐标
        BasEvaluator evaluator = new BasEvaluator(PointFs[1], PointFs[2]);
        ValueAnimator valueAnim = ValueAnimator.ofObject(evaluator, PointFs[0], PointFs[3]);
        valueAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // TODO Auto-generated method stub
                PointF p = (PointF) animation.getAnimatedValue();
                iv.setX(p.x);
                iv.setY(p.y);
                iv.setAlpha(1 - animation.getAnimatedFraction()); // 透明度

            }
        });
        valueAnim.setTarget(iv);
        valueAnim.setDuration(2000);
        valueAnim.setInterpolator(interpolators[new Random().nextInt(4)]);
        return valueAnim;
    }

    private PointF[] getPointFs(ImageView iv) {
        // TODO Auto-generated method stub
        PointF[] PointFs = new PointF[4];
        PointFs[0] = new PointF(); // p0
        PointFs[0].x = ((int) mWidth);
        PointFs[0].y = mHeight;

        PointFs[1] = new PointF(); // p1
        PointFs[1].x = new Random().nextInt(mWidth);
        PointFs[1].y = new Random().nextInt(mHeight / 2) + mHeight / 2 + params.height;

        PointFs[2] = new PointF(); // p2
        PointFs[2].x = new Random().nextInt(mWidth);
        PointFs[2].y = new Random().nextInt(mHeight / 2);

        PointFs[3] = new PointF(); // p3
        PointFs[3].x = new Random().nextInt(mWidth);
        PointFs[3].y = 0;
        return PointFs;
    }
}
import android.content.Context;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.widget.Toast;

public class MyGestureListener extends SimpleOnGestureListener {
  
    private Context mContext;
      
    MyGestureListener(Context context) {
        mContext = context;  
    }  
      
    @Override
    public boolean onDown(MotionEvent e) {
        Toast.makeText(mContext, "DOWN " + e.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public void onShowPress(MotionEvent e) {
        Toast.makeText(mContext, "SHOW " + e.getAction(), Toast.LENGTH_SHORT).show();
    }  
  
    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        Toast.makeText(mContext, "SINGLE UP " + e.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
                            float distanceX, float distanceY) {
        Toast.makeText(mContext, "SCROLL " + e2.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public void onLongPress(MotionEvent e) {
        Toast.makeText(mContext, "LONG " + e.getAction(), Toast.LENGTH_SHORT).show();
    }  
  
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {
        Toast.makeText(mContext, "FLING " + e2.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Toast.makeText(mContext, "DOUBLE " + e.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        Toast.makeText(mContext, "DOUBLE EVENT " + e.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
  
    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        Toast.makeText(mContext, "SINGLE CONF " + e.getAction(), Toast.LENGTH_SHORT).show();
        return false;  
    }  
}  

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-04 13:32:50  更:2022-01-04 13:34:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:24:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码