乱七八糟小结
原生TabLayout零碎设置
原生TabLayout零碎设置
取消点击水波纹效果
app:tabRippleColor="@null"
在tab少的情况下不让tab平分父布局或者tab多的情况下需要滑动查看:tabmode属性设置可滑动
app:tabMode="scrollable
设置tab之间的间隔margin或设置每个tab背景样式:从背景下手,背景里面设置间隔
效果像这样
drawabke文件下 tab_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<!--<shape>
<solid android:color="#ffffff"/>
<corners android:topLeftRadius="10dp" android:topRightRadius="10dp" />
</shape>-->
<!--为了让TabLayout内部的Tab有间隔,暂时找不到其他设置方法,只能在背景图形里面设置间隔-->
<layer-list>
<item>
<shape>
<solid android:color="@android:color/transparent"/>
</shape>
</item>
<item android:left="10dp" android:right="10dp">
<shape>
<corners android:radius="10dp" />
<solid android:color="@color/white"/>
</shape>
</item>
</layer-list>
</item>
<item android:state_selected="false">
<!--<shape>
<solid android:color="#bcbcbc"/>
<corners android:topLeftRadius="10dp" android:topRightRadius="10dp" />
</shape>-->
<layer-list>
<item>
<shape>
<solid android:color="@android:color/transparent"/>
</shape>
</item>
<item android:left="10dp" android:right="10dp">
<shape>
<corners android:radius="10dp" />
<solid android:color="@color/white"/>
</shape>
</item>
</layer-list>
</item>
</selector>
使用
app:tabBackground="@drawable/download_tab_bg_selector"`
设置tab内边距padding
app:tabMinWidth="0dp"
app:tabPaddingBottom="0dp"
app:tabPaddingEnd="25dp"
app:tabPaddingStart="25dp"
app:tabPaddingTop="0dp"
设置文字大小,在 style 文件里添加下面这段代码
(如果要分别设置选中文字和未选中文字大小,建议不要使用原生,使用第三方,原生麻烦)
<style name="TabLayoutTextSize">
<item name="android:textSize">12sp</item>
</style>
设置选中文字颜色
app:tabSelectedTextColor="@color/orange"
设置未选中文字颜色
app:tabTextColor="@color/black"
SharedPreferences(存取删除)
文件的访问权限以及文件数据写入方式
Activity.MODE_PRIVATE,//默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容
Activity.MODE_WORLD_READABLE,//表示当前文件可以被其他应用读取,
Activity.MODE_WORLD_WRITEABLE,//表示当前文件可以被其他应用写入;
Activity.MODE_APPEND//该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件
存
SharedPreferences sharedPreferences = getSharedPreferences("文件名", MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPre.edit();
edit.putString("KEY", "KEYVALUE");
edit.apply();
取
SharedPreferences sharedPreferences = getSharedPreferences("文件名", MODE_PRIVATE);
String accessToken = sharedPre.getString("KEY", "KEYVALUE");
清除
//清除指定数据
SharedPreferences sharedPreferences = getSharedPreferences("文件名", MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPre.edit();
editor.remove("KEY");
edit.apply();
//清除所有数据
SharedPreferences sharedPreferences = getSharedPreferences("文件名", MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPre.edit();
editor.clear();
edit.apply();
ImageView转换成Bitmap
Bitmap image = ((BitmapDrawable)iv.getDrawable()).getBitmap();
本地资源图片转换成Bitmap
//第一种方法
Bitmap bitmap = ((BitmapDrawable)context.getResources().getDrawable(R.mipmap.ic_launcher)).getBitmap();
//第二种
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
图片保存到相册
/*
* 保存文件,文件名为当前日期
*/
public static void saveBitmap(Activity content, Bitmap bitmap) {
DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
String bitName = format.format(new Date()) + ".JPEG";
String fileName;
File file;
if (Build.BRAND.equals("Xiaomi")) { // 小米手机
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" + bitName;
} else { // Meizu 、Oppo
fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + bitName;
}
file = new File(fileName);
if (file.exists()) {
file.delete();
}
FileOutputStream out;
try {
out = new FileOutputStream(file);
// 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)) {
out.flush();
out.close();
// 插入图库
//MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), bitName, null);
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
content.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
ToastUtil.showShort("图片已保存到手机相册");
} else {
ToastUtil.showShort("图片保存失败");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 发送广播,通知刷新图库的显示
content.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName)));
}
SQLite基础使用
GreenDao基础使用
快速实现根据链接生成二维码
implementation 'cn.yipianfengye.android:zxing-library:2.2'
/**
*第一个参数是要生成二维码的链接
*第二、三个参数是生成二维码的宽与高
*第四次参数是添加二维码的logo(不需要添加logo就不用写第四个参数) BitmapFactory.decodeResource(context.getResources(), R.mipmap.logo)
*/
Bitmap qrBitmap = (Bitmap) CodeUtils.createImage("https://www.baidu.com/", 300, 300, null);
View转换成图片(界面可见的情况下)
private Bitmap viewToBitmap(View v) {
int width = v.getWidth();
int height = v.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
v.draw(canvas);
return bitmap;
}
使用:
Bitmap bitmap = viewToBitmap(poster);
View转换成图片(界面不可见的情况下)
public void measureSize(Activity activity) {
//将布局转化成view对象
View viewBitmap = LayoutInflater.from(activity).inflate(R.layout.share_poster, null);
View viewById = viewBitmap.findViewById(R.id.poster);
WindowManager manager = activity.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int width = outMetrics.widthPixels;
int height = outMetrics.heightPixels;
//然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:
layoutView(viewById, width, height, activity);
}
public void layoutView(final View viewBitmap, int width, int height, Activity activity) {
// 整个View的大小 参数是左上角 和右下角的坐标
viewBitmap.layout(0, 0, width, height);
int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.AT_MOST);
viewBitmap.measure(measuredWidth, measuredHeight);
viewBitmap.layout(0, 0, viewBitmap.getMeasuredWidth(), viewBitmap.getMeasuredHeight());
final ImageView imageView = viewBitmap.findViewById(R.id.QR_code);
Bitmap qrBitmap = (Bitmap) CodeUtils.createImage("https://www.baidu.com/", 300, 300, null);
imageView.setImageBitmap(qrBitmap);
//View bitmap
Bitmap bitmap = viewSaveToImage(viewBitmap);
//分享图片
sharePicture(bitmap, 0);
}
private Bitmap viewSaveToImage(View view) {
view.setDrawingCacheEnabled(true);
view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
view.setDrawingCacheBackgroundColor(Color.WHITE);
// 把一个View转换成图片
Bitmap cachebmp = viewConversionBitmap(view);
view.destroyDrawingCache();
return cachebmp;
}
public Bitmap viewConversionBitmap(View v) {
int w = v.getWidth();
int h = v.getHeight();
if (w <= 0 || h <= 0) {
Toast.makeText(this, "view's width or height are <= 0", Toast.LENGTH_SHORT).show();
return null;
}
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bmp);
c.drawColor(Color.WHITE);
/** 如果不设置canvas画布为白色,则生成透明 */
v.layout(0, 0, w, h);
v.draw(c);
return bmp;
}
使用:
measureSize(ShareActivity.this);
//layoutView()在这个方法里获取到bitmap之后进行分享图片等操作
饺子JzvdStd播放器零碎设置
基础使用
布局
<cn.jzvd.JzvdStd
android:id="@+id/vv"
android:layout_width="match_parent"
android:layout_height="180dp" />
播放时使用:
vv.setUp("http://ips.ifeng.com/video19.ifeng.com/video09/2014/06/16/1989823-102-086-0009.mp4",
title",
JzvdStd.SCREEN_NORMAL);
重复播放,自定义一个类继承JzvdStd在重写onStateAutoComplete方法在里面加startVideo();
@Override
public void onStateAutoComplete() {
super.onStateAutoComplete();
//Log.i(TAG, "Auto complete");
startVideo();
}
边播放边缓存(原文链接在这里)
导入第三方库
implementation 'com.danikula:videocache:2.7.0'
在Application中配置
private HttpProxyCacheServer proxy;
public static HttpProxyCacheServer getVideoCacheProxy(Context context) {
ApplicationController app = (ApplicationController) context.getApplicationContext();
return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
}
private HttpProxyCacheServer newProxy() {
return new HttpProxyCacheServer(this);
}
播放时使用:
jzvdStd.setUp(ApplicationController.getVideoCacheProxy(this).
getProxyUrl("http://ips.ifeng.com/video19.ifeng.com/video09/2014/06/16/1989823-102-086-0009.mp4"),
"title",
JzvdStd.SCREEN_NORMAL);
设置有无声音,在自定义类中重写onPrepared方法
@Override
public void onPrepared() {
super.onPrepared();
//播放声音
mediaInterface.setVolume(1f, 1f);
//不播放声音
//mediaInterface.setVolume(0f, 0f);
}
设置进度条隐藏或者设置隐藏暂停开始按钮不能点击
在JzvdStd远吗里面找布局名称然后全局搜索,自己把想隐藏的隐藏掉
获取指定日期到当前时间的相差时长(天时分秒)进行倒计时
业务逻辑
后台返回指定日期时间戳 - 当下时间时间戳 = 相差时长(13位 单位毫秒)
代码实现
/**
* time 指定日期时间戳
* currentTime 当前时间时间戳
* */
long currentTime = new Date().getTime();
long duration = time - currentTime;
//第一个参数就是时间的总值,换算成毫秒值,第二个代表以毫秒来计算
countDownTimer = new CountDownTimer(duration, 1000) {
@SuppressLint("SetTextI18n")
@Override
public void onTick(long millisUntilFinished) {
long day = millisUntilFinished / (1000 * 24 * 60 * 60); //单位天
long hour = (millisUntilFinished - day * (1000 * 24 * 60 * 60)) / (1000 * 60 * 60);
//单位时
long minute = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60)) / (1000 * 60);
//单位分
long second = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60) - minute * (1000 * 60)) / 1000;
//单位秒
startTaskDjs.setText(day+"天"+hour + "时" + minute + "分" + second + "秒");
}
@Override
public void onFinish() {
}
};
countDownTimer.start();
onDestroy()方法记得要关闭,不关闭会出现内存溢出
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
countDownTimer = null;
}
}
时间戳转换为年月日格式
Date dat = new Date(time);
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(dat);
//输出 例如 2021-07-01 10:00:00
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
//输出 例如 2021年07月01日10时00分00秒
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒", Locale.CHINA);
//输出 例如 07月01日10时
SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日HH时", Locale.CHINA);
String sb = sdf.format(gc.getTime());
startTaskTitle.setText(sb+" 敬请期待");
年月日格式转换为时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
long time = 0;
try {
time = sdf.parse("2021-07-01 10:00:00").getTime();
} catch (ParseException e) {
e.printStackTrace();
}
//time 就是转换后时间戳
RecycleView刷新
刷新全部可见的item,notifyDataSetChanged()
刷新指定item,notifyItemChanged(int)
局部刷新,notifyItemChanged(int, Object) (刷新某个指定View)
BaseQuickAdapter
public class TestAdapter extends BaseQuickAdapter<GmBean, BaseViewHolder> {
public static final int AAA = 001;
public TestAdapter() {
super(R.layout.test_item, null);
}
@Override
protected void convert(BaseViewHolder helper, GmBean item) {
//不使用
}
@Override
public void onBindViewHolder(@NonNull BaseViewHolder holder, int position, @NonNull List<Object> payloads) {
super.onBindViewHolder(holder, position, payloads);
if (payloads.isEmpty()) {
RequestOptions options = new RequestOptions()
.transform(new MultiTransformation(new CenterCrop(), new RoundedCorners(15)));
ImageView iconIv = holder.getView(R.id.icon_ic);
TextView gameName = holder.getView(R.id.game_name);
Glide.with(mContext)
.load(getData().get(position).getImg())
.apply(options)
.into(iconIv);
gameName.setText(getData().get(position).getName());
} else {
int type = (int) payloads.get(0);
switch (type) {
case AAA:
TextView tv = holder.getView(R.id.game_name);
List<GmBean> data = getData();
tv.setText(data.get(position).getName());
break;
}
}}
}
Activity
List<GmBean> data = new GmBean().getData();
rv.setLayoutManager(new LinearLayoutManager(this));
TestAdapter testAdapter = new TestAdapter();
rv.setAdapter(testAdapter);
testAdapter.setNewData(data);
testAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
data.remove(position);
data.add(position,new GmBean("天天向上"));
testAdapter.notifyItemChanged(position, TestAdapter.AAA);//局部刷新
//testAdapter.notifyItemChanged(position);//刷新指定item
//notifyDataSetChanged();//刷新指定item
}
});
RecyclerView.Adapter
public class TestAdapter extends RecyclerView.Adapter<TestAdapter1.TestViewHolder> {
public static final int AAA = 001;
private Context context;
private List<GmBean> mDatas;
public TestAdapter(Context context, List<GmBean> mDatas) {
this.context = context;
this.mDatas = mDatas;
}
@NonNull
@Override
public TestViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new TestViewHolder(LayoutInflater.from(context).inflate(R.layout.test_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull TestViewHolder holder, int position, @NonNull List<Object> payloads) {
if (payloads.isEmpty()) {
RequestOptions options = new RequestOptions()
.transform(new MultiTransformation(new CenterCrop(), new RoundedCorners(15)));
Glide.with(context)
.load(mDatas.get(position).getImg())
.apply(options)
.into(holder.img);
holder.tv.setText(mDatas.get(position).getName());
} else {
int type = (int) payloads.get(0);
switch (type) {
case AAA:
holder.tv.setText(mDatas.get(position).getName());
break;
}
}
// 如果设置了回调,则设置点击事件
holder.cut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (rvItemClickListener != null) rvItemClickListener.OnRvItemClickListener(holder.getAdapterPosition());
}
});
}
@Override
public void onBindViewHolder(@NonNull TestViewHolder holder, int position) {
}
class TestViewHolder extends RecyclerView.ViewHolder {
TextView tv;
ImageView img;
ImageView cut;
public TestViewHolder(View view) {
super(view);
tv = (TextView) view.findViewById(R.id.game_name);
img = (ImageView) view.findViewById(R.id.icon_ic);
cut = (ImageView) view.findViewById(R.id.cut);
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
public interface onRvItemClickListener {
void OnRvItemClickListener(int position);
}
private onRvItemClickListener rvItemClickListener;
public void setRvItemClickListener(onRvItemClickListener rvItemClickListener) {
this.rvItemClickListener = rvItemClickListener;
}
}
Activity
List<GmBean> data = new GmBean().getData1();
rv.setLayoutManager(new LinearLayoutManager(this));
TestAdapter1 testAdapter = new TestAdapter1(this,data);
rv.setAdapter(testAdapter);
testAdapter.setRvItemClickListener(new TestAdapter1.onRvItemClickListener() {
@Override
public void OnRvItemClickListener(int position) {
data.remove(position);
data.add(position,new GmBean("天天向上"));
testAdapter.notifyItemChanged(position, TestAdapter.AAA);//局部刷新
//testAdapter.notifyItemChanged(position);//刷新指定item
//notifyDataSetChanged();//刷新指定item
}
});
参考Bean GmBean
public class GmBean {
private String name;
private Integer img;
public GmBean() {
}
public GmBean(String name) {
this.name = name;
}
public GmBean(String name, Integer img) {
this.name = name;
this.img = img;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getImg() {
return img;
}
public void setImg(Integer img) {
this.img = img;
}
public List<GmBean> getData() {
List<GmBean> strings = new ArrayList<>();
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
strings.add(new GmBean("棋牌游戏", R.drawable.qp_gm));
return strings;
}
实时监听网络变化状态
NetStateObserver NetStateReceiver 这两个直接CV
NetStateObserver
public interface NetStateObserver {
void onNetDisconnected();
void onNetConnected(int networkType);
}
NetStateReceiver
public class NetStateReceiver extends BroadcastReceiver {
private List<NetStateObserver> mObservers = new ArrayList<>();
private static class InstanceHolder{
private static final NetStateReceiver INSTANCE = new NetStateReceiver();
}
/**
* 获取连接类型
*
* @param type
* @return
*/
private String getConnectionType(int type) {
String connType = "";
if (type == ConnectivityManager.TYPE_MOBILE) {
connType = "数据流量";
} else if (type == ConnectivityManager.TYPE_WIFI) {
connType = "WIFI网络";
}
return connType;
}
@Override
public void onReceive(Context context, Intent intent) {
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {// 监听wifi的打开与关闭,与wifi的连接无关
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
//Log.e("TAG", "wifiState:" + wifiState);
switch (wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
break;
case WifiManager.WIFI_STATE_DISABLING:
break;
}
}
// 监听网络连接,包括wifi和移动数据的打开和关闭,以及连接上可用的连接都会接到监听
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
//获取联网状态的NetworkInfo对象
NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (info != null) {
//如果当前的网络连接成功并且网络连接可用
if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI || info.getType() == ConnectivityManager.TYPE_MOBILE) {
//Log.i("TAG", getConnectionType(info.getType()) + "连接");
//Toast.makeText(context,"网络已连接", Toast.LENGTH_LONG).show();
for (NetStateObserver observer : mObservers){
observer.onNetConnected(info.getType());
}
}
} else {
//Log.i("TAG", getConnectionType(info.getType()) + "断开");
//Toast.makeText(context, "网络已断开", Toast.LENGTH_LONG).show();
for (NetStateObserver observer : mObservers){
observer.onNetDisconnected();
}
}
}
}
}
public static void unRegisterReceiver(Context context){
context.unregisterReceiver( NetStateReceiver.InstanceHolder.INSTANCE);
}
public static void registerReceiver(Context context){
//注册网络状态监听广播
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver( NetStateReceiver.InstanceHolder.INSTANCE,intentFilter);
}
public static void registerObserver(NetStateObserver observer){
if (observer == null) {
return;
}
if (!NetStateReceiver.InstanceHolder.INSTANCE.mObservers.contains(observer)){
NetStateReceiver.InstanceHolder.INSTANCE.mObservers.add(observer);
}
}
public static void unRegisterObserver(NetStateObserver observer){
if (observer == null) {
return;
}
if (NetStateReceiver.InstanceHolder.INSTANCE.mObservers == null) {
return;
}
NetStateReceiver.InstanceHolder.INSTANCE.mObservers.remove(observer);
}
}
使用
BaseActivity
public abstract class BaseActivity extends SupportActivity implements NetStateObserver {
private boolean isRegistered = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//注册
NetStateReceiver.registerReceiver(this);
NetStateReceiver.registerObserver(this);
isRegistered = true;
}
@Override
protected void onDestroy() {
super.onDestroy();
//解绑
if (isRegistered) {
NetStateReceiver.unRegisterReceiver(this);
NetStateReceiver.unRegisterObserver(this);
}
}
@Override
public void onNetConnected(int networkType) {
if (networkType == ConnectivityManager.TYPE_WIFI) {
ToastUitl.showLongToast(networkType + "已连接");
} else {
ToastUitl.showLongToast("正在使用数据流量,请注意流量消耗");
}
}
@Override
public void onNetDisconnected() {
ToastUitl.showLongToast("网络连接已断开");
}
Activity
@Override
public void onNetDisconnected() {
super.onNetDisconnected();
}
@Override
public void onNetConnected(int networkType) {
super.onNetConnected(networkType);
// do something 例如重新加载数据
}
App字体大小不随系统改变而改变
@Override
public Resources getResources() {
Resources resources = super.getResources();
Configuration configuration = new Configuration();
configuration.setToDefaults();
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return resources;
}