version:1.2.4
fix: update:优化显示未读短信和未接来电,增加手电筒和数据开关
This commit is contained in:
70
app/src/main/java/com/xxpatx/os/custom/CustomContent.java
Normal file
70
app/src/main/java/com/xxpatx/os/custom/CustomContent.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.AttrRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
|
||||
public class CustomContent extends FrameLayout implements CustomContentCallbacks {
|
||||
|
||||
public CustomContent(@NonNull Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public CustomContent(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public CustomContent(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow(boolean fromResume) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHide() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScrollProgressChanged(float progress) {
|
||||
|
||||
}
|
||||
|
||||
// 滑到负一屏是否再允许滑动,true:允许滑动到主屏,false:不允许再滑动
|
||||
@Override
|
||||
public boolean isScrollingAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAdded(View child) {
|
||||
super.onViewAdded(child);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
|
||||
// add by codemx.cn ---- 20190712 ---plus- start
|
||||
// modify by codemx.cn ---- 20190712 ---plus- start
|
||||
public interface CustomContentCallbacks {
|
||||
|
||||
// Custom content is completely shown. {@code fromResume} indicates whether this was caused
|
||||
// by a onResume or by scrolling otherwise.
|
||||
void onShow(boolean fromResume);
|
||||
|
||||
// Custom content is completely hidden
|
||||
void onHide();
|
||||
|
||||
// Custom content scroll progress changed. From 0 (not showing) to 1 (fully showing).
|
||||
void onScrollProgressChanged(float progress);
|
||||
|
||||
// Indicates whether the user is allowed to scroll away from the custom content.
|
||||
boolean isScrollingAllowed();
|
||||
|
||||
}
|
||||
118
app/src/main/java/com/xxpatx/os/custom/GlideEngine.java
Normal file
118
app/src/main/java/com/xxpatx/os/custom/GlideEngine.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.luck.picture.lib.engine.ImageEngine;
|
||||
import com.luck.picture.lib.utils.ActivityCompatHelper;
|
||||
import com.xxpatx.os.R;
|
||||
|
||||
/**
|
||||
* @author:luck
|
||||
* @date:2019-11-13 17:02
|
||||
* @describe:Glide加载引擎
|
||||
*/
|
||||
public class GlideEngine implements ImageEngine {
|
||||
|
||||
/**
|
||||
* 加载图片
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param url 资源url
|
||||
* @param imageView 图片承载控件
|
||||
*/
|
||||
@Override
|
||||
public void loadImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
|
||||
if (!ActivityCompatHelper.assertValidRequest(context)) {
|
||||
return;
|
||||
}
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadImage(Context context, ImageView imageView, String url, int maxWidth, int maxHeight) {
|
||||
if (!ActivityCompatHelper.assertValidRequest(context)) {
|
||||
return;
|
||||
}
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.override(maxWidth, maxHeight)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载相册目录封面
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param url 图片路径
|
||||
* @param imageView 承载图片ImageView
|
||||
*/
|
||||
@Override
|
||||
public void loadAlbumCover(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
|
||||
if (!ActivityCompatHelper.assertValidRequest(context)) {
|
||||
return;
|
||||
}
|
||||
Glide.with(context)
|
||||
.asBitmap()
|
||||
.load(url)
|
||||
.override(180, 180)
|
||||
.sizeMultiplier(0.5f)
|
||||
.transform(new CenterCrop(), new RoundedCorners(8))
|
||||
.placeholder(R.drawable.ps_image_placeholder)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加载图片列表图片
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param url 图片路径
|
||||
* @param imageView 承载图片ImageView
|
||||
*/
|
||||
@Override
|
||||
public void loadGridImage(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView) {
|
||||
if (!ActivityCompatHelper.assertValidRequest(context)) {
|
||||
return;
|
||||
}
|
||||
Glide.with(context)
|
||||
.load(url)
|
||||
.override(200, 200)
|
||||
.centerCrop()
|
||||
.placeholder(R.drawable.ps_image_placeholder)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseRequests(Context context) {
|
||||
Glide.with(context).pauseRequests();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeRequests(Context context) {
|
||||
Glide.with(context).resumeRequests();
|
||||
}
|
||||
|
||||
private GlideEngine() {
|
||||
}
|
||||
|
||||
private static GlideEngine instance;
|
||||
|
||||
public static GlideEngine createGlideEngine() {
|
||||
if (null == instance) {
|
||||
synchronized (GlideEngine.class) {
|
||||
if (null == instance) {
|
||||
instance = new GlideEngine();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
69
app/src/main/java/com/xxpatx/os/custom/ImageViewAdapter.java
Normal file
69
app/src/main/java/com/xxpatx/os/custom/ImageViewAdapter.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.databinding.BindingAdapter;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.xxpatx.os.R;
|
||||
import com.xxpatx.os.utils.GlideLoadUtils;
|
||||
import com.xxpatx.os.utils.TimeUtils;
|
||||
|
||||
public class ImageViewAdapter {
|
||||
@BindingAdapter("android:src")
|
||||
public static void setSrc(ImageView view, Bitmap bitmap) {
|
||||
view.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
@BindingAdapter("android:src")
|
||||
public static void setSrc(ImageView view, int resId) {
|
||||
view.setImageResource(resId);
|
||||
}
|
||||
|
||||
@BindingAdapter("imageUrl")
|
||||
public static void setSrc(ImageView imageView, String url) {
|
||||
Glide.with(imageView.getContext())
|
||||
.load(url)
|
||||
.error(R.mipmap.ic_launcher)
|
||||
.centerCrop()
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义设置图片属性 - 在匹配时自定义命名空间会被忽略
|
||||
*/
|
||||
@BindingAdapter({"imageUrl", "error"})
|
||||
public static void loadImage(ImageView imageView, String url, Drawable error) {
|
||||
Glide.with(imageView.getContext())
|
||||
.load(url)
|
||||
.error(error)
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
@BindingAdapter({"setTime"})
|
||||
public static void setTime(TextView textView, long timestamp) {
|
||||
textView.setText(TimeUtils.transferSecondgToDate(timestamp));
|
||||
}
|
||||
|
||||
@BindingAdapter({"setTemp"})
|
||||
public static void setTemp(TextView textView, String temp) {
|
||||
if (TextUtils.isEmpty(temp)) {
|
||||
textView.setText("N/A ℃");
|
||||
} else {
|
||||
textView.setText(temp + " ℃");
|
||||
}
|
||||
}
|
||||
|
||||
@BindingAdapter({"setTempIcon"})
|
||||
public static void setTempIcon(ImageView imageView, String code) {
|
||||
String imageName = "he" + code;
|
||||
Context context = imageView.getContext();
|
||||
int resId = context.getResources().getIdentifier(imageName, "drawable", context.getPackageName());
|
||||
GlideLoadUtils.getInstance().glideLoad(context, resId, imageView, R.drawable.he999);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class RecyclerItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private int itemSpaceLeft;
|
||||
private int itemSpaceCenter;
|
||||
private int itemNum;
|
||||
|
||||
public RecyclerItemDecoration(int itemSpaceLeft, int itemSpaceCenter, int itemNum) {
|
||||
this.itemSpaceLeft = itemSpaceLeft;
|
||||
this.itemSpaceCenter = itemSpaceCenter;
|
||||
this.itemNum = itemNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
int position = parent.getResources().getDisplayMetrics().widthPixels;
|
||||
//int position = parent.getChildAdapterPosition(view);
|
||||
if (parent.getChildCount() > 0) {
|
||||
if (position % itemNum == 0) { //最左边Item
|
||||
outRect.left = itemSpaceLeft;
|
||||
outRect.right = itemSpaceCenter / 3;
|
||||
} else if (position % itemNum == itemNum - 1) { //最右边Item
|
||||
outRect.left = itemSpaceCenter / 3;
|
||||
outRect.right = itemSpaceLeft;
|
||||
} else { //中间Item
|
||||
outRect.left = itemSpaceCenter / 3;
|
||||
outRect.right = itemSpaceCenter / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class RecyclerViewSpacesItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private final HashMap<String, Integer> mSpaceValueMap;
|
||||
|
||||
public static final String TOP_DECORATION = "top_decoration";
|
||||
public static final String BOTTOM_DECORATION = "bottom_decoration";
|
||||
public static final String LEFT_DECORATION = "left_decoration";
|
||||
public static final String RIGHT_DECORATION = "right_decoration";
|
||||
|
||||
public RecyclerViewSpacesItemDecoration(final HashMap<String, Integer> mSpaceValueMap) {
|
||||
this.mSpaceValueMap = mSpaceValueMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(final Rect outRect, final View view, final RecyclerView parent,
|
||||
final RecyclerView.State state) {
|
||||
if (mSpaceValueMap.get(TOP_DECORATION) != null) {
|
||||
outRect.top = mSpaceValueMap.get(TOP_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(LEFT_DECORATION) != null) {
|
||||
outRect.left = mSpaceValueMap.get(LEFT_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(RIGHT_DECORATION) != null) {
|
||||
outRect.right = mSpaceValueMap.get(RIGHT_DECORATION);
|
||||
}
|
||||
if (mSpaceValueMap.get(BOTTOM_DECORATION) != null) {
|
||||
outRect.bottom = mSpaceValueMap.get(BOTTOM_DECORATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
226
app/src/main/java/com/xxpatx/os/custom/ViewPager2Adapter.java
Normal file
226
app/src/main/java/com/xxpatx/os/custom/ViewPager2Adapter.java
Normal file
@@ -0,0 +1,226 @@
|
||||
package com.xxpatx.os.custom;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 加载显示Fragment的ViewPagerAdapter基类
|
||||
* 提供可以刷新的方法
|
||||
*
|
||||
* @author Fly
|
||||
* @e-mail 1285760616@qq.com
|
||||
* @time 2018/3/22
|
||||
*/
|
||||
public class ViewPager2Adapter extends FragmentStateAdapter {
|
||||
private List<Fragment> mFragmentList;
|
||||
private FragmentManager mFragmentManager;
|
||||
/**
|
||||
* 下面两个值用来保存Fragment的位置信息,用以判断该位置是否需要更新
|
||||
*/
|
||||
private SparseArray<String> mFragmentPositionMap;
|
||||
private SparseArray<String> mFragmentPositionMapAfterUpdate;
|
||||
|
||||
public ViewPager2Adapter(FragmentManager fm, List<Fragment> fragments, Lifecycle lifecycle) {
|
||||
super(fm, lifecycle);
|
||||
mFragmentList = fragments;
|
||||
mFragmentManager = fm;
|
||||
mFragmentList = fragments;
|
||||
mFragmentPositionMap = new SparseArray<>();
|
||||
mFragmentPositionMapAfterUpdate = new SparseArray<>();
|
||||
setFragmentPositionMap();
|
||||
setFragmentPositionMapForUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之前的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMap() {
|
||||
mFragmentPositionMap.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMap.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存更新之后的位置信息,用<hashCode, position>的键值对结构来保存
|
||||
*/
|
||||
private void setFragmentPositionMapForUpdate() {
|
||||
mFragmentPositionMapAfterUpdate.clear();
|
||||
for (int i = 0; i < mFragmentList.size(); i++) {
|
||||
mFragmentPositionMapAfterUpdate.put(Long.valueOf(getItemId(i)).intValue(), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 在此方法中找到需要更新的位置返回POSITION_NONE,否则返回POSITION_UNCHANGED即可
|
||||
// */
|
||||
// @Override
|
||||
// public int getItemPosition(Object object) {
|
||||
// int hashCode = object.hashCode();
|
||||
// //查找object在更新后的列表中的位置
|
||||
// String position = mFragmentPositionMapAfterUpdate.get(hashCode);
|
||||
// //更新后的列表中不存在该object的位置了
|
||||
// if (position == null) {
|
||||
// return POSITION_NONE;
|
||||
// } else {
|
||||
// //如果更新后的列表中存在该object的位置, 查找该object之前的位置并判断位置是否发生了变化
|
||||
// int size = mFragmentPositionMap.size();
|
||||
// for (int i = 0; i < size ; i++) {
|
||||
// int key = mFragmentPositionMap.keyAt(i);
|
||||
// if (key == hashCode) {
|
||||
// String index = mFragmentPositionMap.get(key);
|
||||
// if (position.equals(index)) {
|
||||
// //位置没变依然返回POSITION_UNCHANGED
|
||||
// return POSITION_UNCHANGED;
|
||||
// } else {
|
||||
// //位置变了
|
||||
// return POSITION_NONE;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return POSITION_UNCHANGED;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 将指定的Fragment替换/更新为新的Fragment
|
||||
*
|
||||
* @param oldFragment 旧Fragment
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(Fragment oldFragment, Fragment newFragment) {
|
||||
int position = mFragmentList.indexOf(oldFragment);
|
||||
if (position == -1) {
|
||||
return;
|
||||
}
|
||||
//从Transaction移除旧的Fragment
|
||||
removeFragmentInternal(oldFragment);
|
||||
//替换List中对应的Fragment
|
||||
mFragmentList.set(position, newFragment);
|
||||
//刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定位置的Fragment替换/更新为新的Fragment,同{@link #replaceFragment(Fragment oldFragment, Fragment newFragment)}
|
||||
*
|
||||
* @param position 旧Fragment的位置
|
||||
* @param newFragment 新Fragment
|
||||
*/
|
||||
public void replaceFragment(int position, Fragment newFragment) {
|
||||
Fragment oldFragment = mFragmentList.get(position);
|
||||
removeFragmentInternal(oldFragment);
|
||||
mFragmentList.set(position, newFragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定的Fragment
|
||||
*
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void removeFragment(Fragment fragment) {
|
||||
//先从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//然后从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除指定位置的Fragment,同 {@link #removeFragment(Fragment fragment)}
|
||||
*
|
||||
* @param position
|
||||
*/
|
||||
public void removeFragment(int position) {
|
||||
Fragment fragment = mFragmentList.get(position);
|
||||
//然后从List中移除
|
||||
mFragmentList.remove(fragment);
|
||||
//先从Transaction移除
|
||||
removeFragmentInternal(fragment);
|
||||
//最后刷新Adapter
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Fragment
|
||||
*
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void addFragment(Fragment fragment) {
|
||||
mFragmentList.add(fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定位置插入一个Fragment
|
||||
*
|
||||
* @param position 插入位置
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
public void insertFragment(int position, Fragment fragment) {
|
||||
mFragmentList.add(position, fragment);
|
||||
notifyItemChanged();
|
||||
}
|
||||
|
||||
private void notifyItemChanged() {
|
||||
//刷新之前重新收集位置信息
|
||||
setFragmentPositionMapForUpdate();
|
||||
notifyDataSetChanged();
|
||||
setFragmentPositionMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从Transaction移除Fragment
|
||||
*
|
||||
* @param fragment 目标Fragment
|
||||
*/
|
||||
private void removeFragmentInternal(Fragment fragment) {
|
||||
FragmentTransaction transaction = mFragmentManager.beginTransaction();
|
||||
transaction.remove(fragment);
|
||||
transaction.commitNow();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
return mFragmentList.get(position);
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public SecondFragment getItem(int position) {
|
||||
// return mFragmentList.get(position);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getCount() {
|
||||
// return mFragmentList.size();
|
||||
// }
|
||||
|
||||
/**
|
||||
* 此方法不用position做返回值即可破解fragment tag异常的错误
|
||||
*/
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
// 获取当前数据的hashCode,其实这里不用hashCode用自定义的可以关联当前Item对象的唯一值也可以,只要不是直接返回position
|
||||
return mFragmentList.get(position).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mFragmentList.size();
|
||||
}
|
||||
|
||||
public List<Fragment> getFragments() {
|
||||
return mFragmentList;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user