文章目录

  • 编译错误
  • Kapt编译加速
  • Android12 广播Intent为空
  • 帧率测试
  • 文字自适应
  • 字符串拼接
  • Retrofit Json异常解决
  • 图片状态选择器
  • Cmake文档
  • Android 10 已授权仍提示无读写权限
  • 文本缩略
  • 文本描边
  • gradle 下载
  • 图片换色
  • 圆角
  • ScollerView自动滚动
  • ScollerView EditText自动滚动
  • 系统级定时器
  • Java非空检查
  • 公共头布局
  • Canvas保存图片
  • 返回键
  • 打LOG
  • 申请权限
  • 依赖
  • gradle 重复依赖
  • AAR 引入
  • AAR 修改输出名称
  • Dialog
  • dp,px互转
  • 刷新媒体库
  • 修改状态栏颜色
    • 修改字体颜色
    • 显示隐藏状态栏
  • 布局边框 outlineProvider
  • FragmentPagerAdapter 加载
  • TextView 设置 Drawable
  • 拍照快门声
  • toJsonTree
  • 输出堆栈
  • LIstView
  • 验证并初始化GLS
  • List 嵌套
  • SpannerString
  • 防抖动
编译错误

Caused by: org.gradle.api.internal.tasks.compile.CompilationFailedException: Compilation failed; see the compiler error output for details.

Kapt编译加速

https://www.kotlincn.net/docs/reference/kapt.html

Android12 广播Intent为空

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
解决
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE

帧率测试
    private long callbackNum = 0;private long currentTime = 0L;private long previewTime = 0L;private long dltaTimeSum = 0L;/** 测试频率* 注释:* @author maqi* created at 2021/11/8 16:48* */private void testCallHz() {currentTime = System.currentTimeMillis();dltaTimeSum += (currentTime - previewTime);callbackNum++;if (callbackNum % 100 == 0) {Log.d("testCallHz", "一百次平均时长 " + (dltaTimeSum / callbackNum));callbackNum = 0;dltaTimeSum = 0;}previewTime = currentTime;}
文字自适应
@Overridepublic void onWindowFocusChanged(boolean hasFocus) {super.onWindowFocusChanged(hasFocus);if (hasFocus) {setTvSize(mainGuideTv, mMainGuide.getMeasuredWidth() - dp2px(this, 20), new TextPaint());}}/** 文字自动缩放* 注释:* @author maqi* created at 2022/8/4 16:44* */private void setTvSize(TextView textView, int width, TextPaint textPaint) {int textSizeDp = px2dip(this, textView.getTextSize());String text = textView.getText().toString();textPaint.setTextSize(dp2px(this, textSizeDp));float textwidth = textPaint.measureText(text);if (textwidth > width) {textSizeDp--;textView.setTextSize(textSizeDp);setTvSize(textView, width, textPaint);}}public static int dp2px(Context context, float dpVal) {return (int) TypedValue.applyDimension(1, dpVal, context.getResources().getDisplayMetrics());}public static int px2dip(Context context, float pxValue) {float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}
字符串拼接
<string name="lock_after_timeout_summary_with_exception" msgid="5579064842797188409">"休眠<xliff:g id="TIMEOUT_STRING">%1$s</xliff:g>后(<xliff:g id="TRUST_AGENT_NAME">%2$s</xliff:g>让屏幕保持解锁状态时除外)"</string>
Retrofit Json异常解决
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT
//public List<ListBean> list;class ListBean {}public Object list;public List<ListBean> getList() {try {Gson gson = new Gson();if (list != null) {String json = gson.toJson(list);TypeToken<List<ListBean>> typeToken = new TypeToken<List<ListBean>>() {};return gson.fromJson(json, typeToken.getType());}} catch (Exception e) {Log.d("xxxxx", e.getLocalizedMessage());}return new ArrayList<>();
}
图片状态选择器
//TextView
android:drawableTint="@color/select_text_color"//ImageView
fun ImageView.setSelector(context: Context, drawable_res: Int, color_res: Int) {val icon = ContextCompat.getDrawable(context, drawable_res)val tintIcon = DrawableCompat.wrap(icon!!)val selector_tint = ContextCompat.getColorStateList(context, color_res)DrawableCompat.setTintList(tintIcon, selector_tint)setImageDrawable(tintIcon)
}
Cmake文档

https://developer.android.com/studio/projects/configure-cmake

Android 10 已授权仍提示无读写权限

android:requestLegacyExternalStorage="true"

文本缩略
Paint  paintCenterText = new Paint();
paintCenterText.setColor(textColorCenter);
paintCenterText.setAntiAlias(true);
paintCenterText.setTextScaleX(textScaleX);
paintCenterText.setTypeface(Typeface.MONOSPACE);
paintCenterText.setTextSize(textSize);
String info = TextUtils.ellipsize(contentTexts[i],
new TextPaint(paintCenterText), 300, TextUtils.TruncateAt.END).toString();
文本描边
userTextP?.setShadowLayer(1f, 1f, 1f, Color.parseColor("#FFFFFFFF"));
gradle 下载

https://gradle.org/releases/

图片换色
int textColor = ContextCompat.getColor(requireContext(), R.color.app_color);
mTvPing.setTextColor(textColor);
Drawable d1 = getResources().getDrawable(R.drawable.ic_heart).mutate();
d1.setBounds(0, 0, d1.getMinimumWidth(), d1.getMinimumHeight());
d1.setColorFilter(textColor, PorterDuff.Mode.SRC_ATOP);
mTvPing.setCompoundDrawables(d1, null, null, null);
圆角
final GradientDrawable drawable = new GradientDrawable();drawable.setColor(0xff308EFF);mBtnHomepage.setBackgroundDrawable(drawable);mBtnHomepage.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {drawable.setCornerRadius(mBtnHomepage.getHeight() / 2);}});

/*** 文件名:RoundImageView* 描  述:* 作  者:05878mq* 时  间:2022/9/7 17:11*/
public class RoundImageView extends AppCompatImageView {private final static int mBorderRadius = 20;private Paint mPaint;private Xfermode mXfermode;public RoundImageView(Context context) {this(context, null);}public RoundImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mPaint.setAntiAlias(true);mXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);}@Overrideprotected void onDraw(Canvas canvas) {if (getDrawable() == null) {return;}float mBorderRadiusDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mBorderRadius, getResources().getDisplayMetrics());int sc = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);//画源图像,为一个圆角矩形canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), mBorderRadiusDp, mBorderRadiusDp,mPaint);//设置混合模式mPaint.setXfermode(mXfermode);//画目标图像canvas.drawBitmap(drawableToBitamp(getDrawable()), 0, 0, mPaint);// 还原混合模式mPaint.setXfermode(null);canvas.restoreToCount(sc);}/*** 图片拉升** @param drawable* @return*/private Bitmap drawableToBitamp(Drawable drawable) {float scale = Math.max(getWidth() * 1.0f / drawable.getIntrinsicWidth(), getHeight()* 1.0f / drawable.getIntrinsicHeight());int w = (int) (drawable.getIntrinsicWidth() * scale);int h = (int) (drawable.getIntrinsicWidth() * scale);Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, w, h);drawable.draw(canvas);return bitmap;}
}
ScollerView自动滚动
android:focusable="true"
android:focusableInTouchMode="true"
ScollerView EditText自动滚动
public class NoScollerEditText extends AppCompatEditText implements View.OnTouchListener {public NoScollerEditText(Context context) {this(context, null);}public NoScollerEditText(Context context, AttributeSet attrs) {this(context, attrs, 0);}public NoScollerEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setOnTouchListener(this);}@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {//这句话说的意思告诉父View我自己的事件我自己处理view.requestFocusFromTouch();return false;}
}
系统级定时器
Intent mStartActivity = new Intent(MainActivity.this, MainActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(MainActivity.this,mPendingIntentId,mStartActivity,PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) MainActivity.this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
Java非空检查
 Objects.requireNonNull
公共头布局
//activity 中@Overridepublic boolean onPrepareOptionsMenu(Menu menu) {menu.clear();View view = LayoutInflater.from(this).inflate(R.layout.menu_header, null);((TextView) view.findViewById(R.id.menu_title)).setText(R.string.portfolio);view.findViewById(R.id.add_portfolio).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {}});view.findViewById(R.id.menu_back).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});ActionBar supportActionBar = getActivity().getSupportActionBar();supportActionBar.setDisplayShowCustomEnabled(true);supportActionBar.setHomeButtonEnabled(false);supportActionBar.setDisplayHomeAsUpEnabled(false);supportActionBar.setCustomView(view);return super.onPrepareOptionsMenu(menu);}//header.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="50dp"android:background="@color/app_color"android:gravity="center_vertical"android:orientation="horizontal"><FrameLayoutandroid:id="@+id/menu_back"android:layout_width="@dimen/dp_50"android:layout_height="@dimen/dp_50"><ImageViewandroid:layout_width="@dimen/dp_25"android:layout_height="@dimen/dp_25"android:layout_gravity="center"android:src="@drawable/ic_back"></ImageView></FrameLayout><TextViewandroid:id="@+id/menu_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:textColor="#ffffffff"android:textSize="17sp"></TextView></RelativeLayout>
Canvas保存图片
//bitmap为被绘制的图形,而mIfrBitmap为底图
Paint p = Paint() // 创建一个画笔对象
Matrix mMatrix = Matrix()
mMatrix.setScale(1.0f, 1.0f)
//val mIfrBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)
//saveCanvas.drawBitmap(mIfrBitmap, mMatrix, p)
Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888).also {drawBoxs(Canvas(it).apply { drawBitmap(bitmap, mMatrix, p) })FileUtils.saveBitmap2JpegFile(it, "${System.currentTimeMillis()}_oragin.png");
}

drawBoxs

private fun drawBoxs(mCanvas: Canvas?) {val userTextP = TextPaint() // 创建一个画笔对象var mScale: Float = 1fval WIDTH  =0Lval WIDTH  =0Lvar x = 0var y = 0userTextWidth = density * 150 + 0.5fuserTextHeight = density * 16 + 0.5fuserTextP?.style = Paint.Style.FILLuserTextP?.color = Color.parseColor("#FF000000")userTextP?.isFakeBoldText = true;userTextP?.strokeWidth = textSize.toFloat();userTextP?.setShadowLayer(1f, 1f, 1f, Color.parseColor("#FF000000"));userTextP?.textSize = userTextHeight// - textSize//userTextP?.color = Color.parseColor("#FF56FED4")//mCanvas?.drawText(String.format(mCtx!!.getString(R.string.foramt_human_box), box.distance / 100f, box.angle / 100), x * mScale, y * mScale + userTextHeight, userTextP!!)val format =""mCanvas?.save()val myStaticLayout = StaticLayout(format, userTextP, userTextWidth.toInt(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true)/*判断 是否 超出*/val overWidth: Float = with(WIDTH * mScale - (x * mScale + userTextWidth)) { if (this >= 0) 0f else this }var overHeight: Float = with(y * mScale - myStaticLayout.height) { if (this >= 0) this else 0f }mCanvas?.translate(x * mScale + overWidth, overHeight)myStaticLayout.draw(mCanvas)mCanvas?.restore()
}

保存bitmap

    public static boolean saveBitmap2JpegFile(Bitmap bmp, String bitName)  {boolean flag = false;if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 获得存储卡的路径String sdpath = Environment.getExternalStorageDirectory() + "/";String mSavePath = sdpath + "Meidi/imgs";new File(mSavePath).mkdirs();File f = new File(mSavePath, bitName);try {f.createNewFile();} catch (IOException e) {e.printStackTrace();}FileOutputStream fOut = null;try {fOut = new FileOutputStream(f);bmp.compress(Bitmap.CompressFormat.PNG, 100, fOut);flag = true;} catch (FileNotFoundException e) {e.printStackTrace();}try {fOut.flush();} catch (IOException e) {e.printStackTrace();}try {fOut.close();} catch (IOException e) {e.printStackTrace();}}return flag;}
返回键
 private val TIME_INTERVAL = 2000private var mBackPressed: Long = 0override fun onBackPressed() {if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) {super.onBackPressed()return} else {Toast.makeText(baseContext, "再次点击返回键退出", Toast.LENGTH_SHORT).show()}mBackPressed = System.currentTimeMillis()}
打LOG
public class Logger {/*** ERROR*/public static void e(Class<?> clazz, String msg) {if (BuildConfig.DEBUG) {Log.e(clazz.getSimpleName(), msg + "");}}public static void e(String tag, String msg) {if (BuildConfig.DEBUG) {Log.e(tag, msg + "");}}/*** WARN*/public static void w(Class<?> clazz, String msg) {if (BuildConfig.DEBUG) {Log.w(clazz.getSimpleName(), msg + "");}}public static void w(String tag, String msg) {if (BuildConfig.DEBUG) {Log.w(tag, msg + "");}}/*** INFO*/public static void i(Class<?> clazz, String msg) {if (BuildConfig.DEBUG) {Log.i(clazz.getSimpleName(), msg + "");}}public static void i(String tag, String msg) {if (BuildConfig.DEBUG) {Log.i(tag, msg + "");}}/*** DEBUG*/public static void d(Class<?> clazz, String msg) {if (BuildConfig.DEBUG) {Log.d(clazz.getSimpleName(), msg + "");}}public static void d(String tag, String msg) {if (BuildConfig.DEBUG) {Log.d(tag, msg + "");}}/*** VERBOSE*/public static void v(Class<?> clazz, String msg) {if (BuildConfig.DEBUG) {Log.v(clazz.getSimpleName(), msg + "");}}public static void v(String tag, String msg) {if (BuildConfig.DEBUG) {Log.v(tag, msg + "");}}}
申请权限
//android 7.0及以上需要动态申请权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
依赖
gradle 重复依赖
  1. compileOnly 'com.google.code.gson:gson:2.8.5'

  2. configurations.all{ resolutionStrategy { force 'com.google.code.gson:gson:2.8.5' } }

  3. configurations { // all*.exclude group: 'com.android.support', module: 'support-v13' all*.exclude group: 'com.android.support' }

  4. gradlew :lib_expert:dependenciecls 导出依赖

  5. 推荐Gradle依赖--管理依赖的版本 https://www.jianshu.com/p/ee1477693d8e

AAR 引入

implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])

AAR 修改输出名称
apply plugin: 'com.android.library'
android{··libraryVariants.all { variant ->if (variant.buildType.name == "debug") {variant.getPackageLibrary().destinationDir = new File(project.rootDir.absolutePath + "/${project.name}/build/outputs/debug/aar")}/*旧版本无效*/
//        if (variant.buildType.name == 'release') {//            variant.outputs.all { output ->
//                println("outputFile    ${outputFile}")
//                println("outputFileName before    ${outputFileName}")
//                def outputFile = output.outputFile
//                if (outputFile != null && outputFile.name.endsWith('release.aar')) {//                    outputFileName = "tnn-${project.name}${variant.flavorName}-${variant.buildType.name}.aar"
//                    println("outputFileName  after   ${outputFileName}")
//                }
//            }
//        }if (variant.buildType.name == 'release') {//variant.getPackageLibrary().destinationDir = new File(project.rootDir.absolutePath + "/${project.name}/build/outputs/release/aar")variant.assemble.doLast {variant.outputs.all { output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('release.aar')) {def date = new Date()def formattedDate = date.format('yyyy-MM-dd-HH-mm-ss')def fileName = "tnn${variant.flavorName}-${formattedDate}-${variant.buildType.name}"def outputPath = project.rootDir.absolutePath + "/${project.name}/build/outputs/release/aar"copy {from outputFileinto outputPathrename { fileName + ".aar" }}println("outputFile    ${outputFile}")println("outputFileName     ${outputFileName}")delete outputFile.parentFile}}}}}
}
Dialog
  1. 继承BaseDialog
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;public class BaseDialog extends Dialog {private static final String TAG = "BaseDialog";private Context context;private int layoutId;public View view;public BaseDialog(Context context) {super(context);init(context, 0);}public BaseDialog(Context context, int theme) {super(context, theme);init(context, 0);}public BaseDialog(Context context, int theme, int LayoutId) {super(context, theme);init(context, LayoutId);}private void init(Context context, int layoutId) {this.context = context;this.layoutId = layoutId;}@SuppressLint("InflateParams")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);if (layoutId != 0) {view = LayoutInflater.from(context).inflate(layoutId, null);this.setContentView(view);}initView();}public void initView() {// 初始化默认的dialog,对于其他的可以复写这个方法来完成}public void setWidthHight(int dialogWidthDp, int dialogHightDp) {WindowManager.LayoutParams params = this.getWindow().getAttributes();params.width = dialogWidthDp;params.height = dialogHightDp;this.getWindow().setAttributes(params);}public void setPostion(int offx, int offy) {Window dialogWindow = this.getWindow();WindowManager.LayoutParams lp = dialogWindow.getAttributes();dialogWindow.setGravity(Gravity.CENTER);lp.x = offx;lp.y = offy;/*Resources re = context.getResources();lp.x = (int) re.getDimension(R.dimen.dialog_move_x);lp.y = (int) re.getDimension(R.dimen.dialog_move_y);*/dialogWindow.setAttributes(lp);}}
  1. 重写Dialog的状态栏
    注意:高度不要写 WindowManager.LayoutParams.MATCH_PARENT,这样会覆盖Activity的状态栏,这样你的顶部一片白,且无法修改状态栏字体,此题误解
    尝试了2天 发现只有Activity才能修改 状态栏字体颜色 于是给大家如下
 WindowManager.LayoutParams p = win.getAttributes(); // 获取对话框当前的参数值p.width = WindowManager.LayoutParams.MATCH_PARENT;p.height = ScreenUtils.Companion.getScreenHeight(mContext);//高度不占用状态栏p.flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE;//黑色字体win.setAttributes(p);
fun getScreenHeight(ctx: Context): Int {return ctx.resources.displayMetrics.heightPixels}fun getScreenWidth(ctx: Context): Int {return ctx.resources.displayMetrics.widthPixels}
  1. 写一个工具类
public void show() {AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.My_Theme_Dialog_Alert);alertDialog = builder.create();alertDialog.show();alertDialog.setCanceledOnTouchOutside(false);Window win = alertDialog.getWindow();win.setWindowAnimations(R.style.dialog_animation_style);LayoutInflater factory = LayoutInflater.from(context);final View view = factory.inflate(R.layout.dialog_download, null);win.setContentView(view);// 实现弹出软键盘win.clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);WindowManager.LayoutParams p = win.getAttributes(); // 获取对话框当前的参数值p.width = context.getResources().getDimensionPixelOffset(R.dimen.dialog_width);//WindowManager.LayoutParams p = win.getAttributes(); // 获取对话框当前的参数值//p.width = WindowManager.LayoutParams.MATCH_PARENT;//p.height = WindowManager.LayoutParams.MATCH_PARENT;win.setAttributes(p);
}

style

    <!-- 完全自定义的Dialog --><style name="My_Theme_Dialog_Alert" parent="@android:style/Theme"><item name="windowNoTitle">true</item><item name="android:windowBackground">@drawable/guide_dialog_background</item><item name="android:windowContentOverlay">@null</item><item name="android:backgroundDimEnabled">true</item><item name="android:windowSoftInputMode">adjustPan</item><item name="android:windowIsFloating">true</item></style>

Animation

 <style name="dialog_animation_style"><item name="android:windowEnterAnimation">@anim/anim_show_in</item><item name="android:windowExitAnimation">@anim/anim_show_out</item></style>

简单的loading

   val loadingAlertDialog: AlertDialog by lazy {AlertDialog.Builder(this, R.style.dialog_style).create().apply {val inflate = View.inflate(this@BaseActivity, R.layout.loading, null)setView(inflate)val imageView = inflate.findViewById<ImageView>(R.id.loading_view)val animationDrawable =ContextCompat.getDrawable(this@BaseActivity,R.drawable.anim_loading_view) as AnimationDrawableanimationDrawable.start()setCancelable(true)setCanceledOnTouchOutside(false)imageView.setImageDrawable(animationDrawable)}}

style

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"><ImageViewandroid:id="@+id/loading_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/shape_black" />
</FrameLayout>
<!--背景-->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><corners android:radius="@dimen/margin_5dp"></corners><solid android:color="@color/black"></solid><size android:height="50dp" android:width="50dp"></size>
</shape><!--动画 anim_loading_view-->
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"><item android:drawable="@mipmap/refresh_loading01" android:duration="100" /><item android:drawable="@mipmap/refresh_loading02" android:duration="100" /><item android:drawable="@mipmap/refresh_loading03" android:duration="100" /><item android:drawable="@mipmap/refresh_loading04" android:duration="100" /><item android:drawable="@mipmap/refresh_loading05" android:duration="100" /><item android:drawable="@mipmap/refresh_loading06" android:duration="100" /><item android:drawable="@mipmap/refresh_loading07" android:duration="100" /><item android:drawable="@mipmap/refresh_loading08" android:duration="100" /><item android:drawable="@mipmap/refresh_loading09" android:duration="100" /><item android:drawable="@mipmap/refresh_loading10" android:duration="100" /><item android:drawable="@mipmap/refresh_loading11" android:duration="100" /><item android:drawable="@mipmap/refresh_loading12" android:duration="100" />
</animation-list>

图片链接

3 适用于全屏


public abstract class BaseDialog extends Dialog {public BaseDialog(@NonNull Context context, @StyleRes int themeResId) {super(context, themeResId);setCancelable(false);}public BaseDialog(@NonNull Context context) {this(context, R.style.DialogTheme);}protected abstract int getLayoutResId();protected abstract void onCreateView();public int getViewGravity() {return Gravity.CENTER;}public int getLayoutParamsWidth() {return WindowManager.LayoutParams.MATCH_PARENT;}public int getLayoutParamsHeight() {return WindowManager.LayoutParams.WRAP_CONTENT;}@Overridepublic final void setCancelable(boolean flag) {super.setCancelable(flag);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Window window = getWindow();window.getDecorView().setPadding(0, 0, 0, 0);WindowManager.LayoutParams layoutParams = window.getAttributes();layoutParams.width = getLayoutParamsWidth();layoutParams.height = getLayoutParamsHeight();window.setAttributes(layoutParams);window.setGravity(getViewGravity());setContentView(getLayoutResId()); onCreateView();setCanceledOnTouchOutside(false);}
}
dp,px互转
   /*** 根据手机的分辨率从 dp 的单位 转成为 px(像素)*/public static int dip2px(Context context, float dpValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}/*** 根据手机的分辨率从 px(像素) 的单位 转成为 dp*/public static int px2dip(Context context, float pxValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (pxValue / scale + 0.5f);}
刷新媒体库

class MediaUtils {companion object {/*** 刷新media显示,使用MediaScannerConnection.scanFile会导致MediaScanner ServiceConnectionLeaked低概率错误,因此改用广播的方式* 2017.11.17改为scanFile,改成广播的方式会导致SD卡内容无法及时刷新** @param ctx* @param filePath*/fun noticeMediaScanner(ctx: Context, filePath: String?) {if (null == filePath) {return}MediaScannerConnection.scanFile(ctx,arrayOf(filePath), null) { _, _ -> }}}init {throw AssertionError("cannot be instantiated")}}
修改状态栏颜色
    fun initStatusBar() {var statusBarView: View? = nullif (statusBarView == null) {//利用反射机制修改状态栏背景val identifier = resources.getIdentifier("statusBarBackground", "id", "android")statusBarView = window.findViewById<View>(identifier)}if (statusBarView != null) {statusBarView.setBackgroundResource(R.drawable.top_bar_background)}}
修改字体颜色
 /*** 界面设置状态栏字体颜色*/fun changeStatusBarTextImgColor(isBlack: Boolean) {if (isBlack) {//设置状态栏黑色字体window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} else {//恢复状态栏白色字体window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE}}
显示隐藏状态栏
    fun hideStatusBar() {window.decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
//                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
//                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONor View.SYSTEM_UI_FLAG_FULLSCREENor View.SYSTEM_UI_FLAG_IMMERSIVE)if (Build.VERSION.SDK_INT < 30) {window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);} else {val v = window.decorViewval uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATIONor View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN)v.setSystemUiVisibility(uiOptions)}}fun showStatusBar() {window.decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLEor View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONor View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)}
布局边框 outlineProvider
 android:outlineProvider="bounds"
   ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {@Overridepublic void getOutline(View view, Outline outline) {outline.setOval(0,0,mImg.getWidth(), mImg.getHeight());}};mImg.setOutlineProvider(viewOutlineProvider);mImg.setClipToOutline(true);
FragmentPagerAdapter 加载

import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.view.ViewGroup;import com.proginn.base.BaseFragment;import java.util.List;public class BaseFragmentAdapter extends FragmentPagerAdapter {private List<BaseFragment> fragments;private String[] titles;private FragmentManager fm;public BaseFragmentAdapter(FragmentManager fm, List<BaseFragment> fragments, String[] titles) {super(fm);this.fm = fm;this.titles = titles;this.fragments = fragments;}@Overridepublic Fragment getItem(int position) {return fragments.get(position);}@Overridepublic int getCount() {return fragments.size();}@Nullable@Overridepublic CharSequence getPageTitle(int position) {return titles[position];}@Overridepublic Object instantiateItem(ViewGroup container, int position) {FragmentTransaction ft = fm.beginTransaction();for (int i = 0; i < getCount(); i++) {//通过遍历清除所有缓存final long itemId = getItemId(i);//得到缓存fragment的名字String name = makeFragmentName(container.getId(), itemId);//通过fragment名字找到该对象BaseFragment fragment = (BaseFragment) fm.findFragmentByTag(name);if (fragment != null) {//移除之前的fragmentft.remove(fragment);}}//重新添加新的fragment:最后记得commitft.add(container.getId(), getItem(position)).attach(getItem(position)).commit();return getItem(position);}@Overridepublic int getItemPosition(Object object) {return POSITION_NONE;}/*** 得到缓存fragment的名字** @param viewId* @param id* @return*/private String makeFragmentName(int viewId, long id) {return "android:switcher:" + viewId + ":" + id;}
}
TextView 设置 Drawable
mTvWorkWay.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.icon_selectmore_active, 0);
拍照快门声
var audioManager: AudioManager = requireActivity().getSystemService(Context.AUDIO_SERVICE) as AudioManager
var ringerMode = audioManager.getRingerMode()mMediaActionSound = MediaActionSound()
mMediaActionSound.load(MediaActionSound.SHUTTER_CLICK)//铃音模式
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {mMediaActionSound.play(MediaActionSound.SHUTTER_CLICK)
}
toJsonTree

//避免泛型擦除

  /*** 用于保存集合** @param key  key* @param list 集合数据* @return 保存结果*/
public static <T> boolean putListData(SharedPreferences sp, String key, LinkedList<T> list) {boolean result;SharedPreferences.Editor editor = sp.edit();JsonArray array = new JsonArray();Gson gson = new Gson();for (int i = 0; i < list.size(); i++) {JsonElement obj = gson.toJsonTree(list.get(i));array.add(obj);}
}
/*** 获取保存的List** @param key key* @return 对应的Lis集合*/public static <T> LinkedList<T> getListData(SharedPreferences sp, String key, Class<T> cls) {LinkedList<T> list = new LinkedList<>();String json = sp.getString(key, "");if (!json.equals("") && json.length() > 0) {Gson gson = new Gson();JsonArray array = new JsonParser().parse(json).getAsJsonArray();for (JsonElement elem : array) {list.add(gson.fromJson(elem, cls));}}return list;}
输出堆栈
        Writer writer = new StringWriter();PrintWriter printWriter = new PrintWriter(writer);ex.printStackTrace(printWriter);Throwable cause = ex.getCause();while (cause != null) {cause.printStackTrace(printWriter);cause = cause.getCause();}printWriter.close();String result = writer.toString();
LIstView
public View getView(int position, View convertView, ViewGroup parent) {Holder holder;if (convertView == null) {holder = new Holder();
···convertView.setTag(holder);} else {holder = (Holder) convertView.getTag();}
}
static class Holder {}
验证并初始化GLS
private GLFrameSurface mGLSurfaceView;
private GLFrameRenderer mRenderer;
private boolean supportsEs2;public class GLFrameSurface extends GLSurfaceView {String TAG = "GLFrameSurface";public GLFrameSurface(Context context) {super(context);}public GLFrameSurface(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onAttachedToWindow() {Log.v(TAG, "surface onAttachedToWindow()");super.onAttachedToWindow();// setRenderMode() only takes effectd after SurfaceView attached to window!// note that on this mode, surface will not render util GLSurfaceView.requestRender() is// called, it's good and efficient -v-setRenderMode(RENDERMODE_WHEN_DIRTY);Log.v(TAG, "surface setRenderMode RENDERMODE_WHEN_DIRTY");}
}
private void initFusionGlSurface() {mGLSurfaceView = new GLFrameSurface(this);mGLSurfaceView.setVisibility(View.INVISIBLE);ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;if (supportsEs2) {// Request an OpenGL ES 2.0 compatible context.mGLSurfaceView.setEGLContextClientVersion(2);mRenderer = new GLFrameRenderer(this, mGLSurfaceView);mGLSurfaceView.setRenderer(mRenderer);}mAnalyserIfrCameraShow.addView(mGLSurfaceView);// 这句代码很重要,没有它会出现异常情况;mGLSurfaceView.setZOrderMediaOverlay(true);}
List 嵌套
public class ScrollListView extends ListView {public ScrollListView(Context context) {super(context);}public ScrollListView(Context context, AttributeSet attrs) {super(context, attrs);}public ScrollListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
SpannerString

可点击,可变色字符串

  weightTip.setMovementMethod(LinkMovementMethod.getInstance());
  @NonNullpublic static SpannableString createAgreementString(@NonNull final Activity activity, @NonNull String format) {String smrz = new String("实名个人信息");String zxkf = new String("在线客服");String agreementString = String.format(Locale.ENGLISH, format, "实名个人信息认证", "在线客服");SpannableString spannableString = new SpannableString(agreementString);int smrzSI = agreementString.indexOf(smrz);int zxkfSI = agreementString.indexOf(zxkf);spannableString.setSpan(new ClickableSpan() {@Overridepublic void updateDrawState(TextPaint ds) {super.updateDrawState(ds);ds.setColor(activity.getResources().getColor(R.color.app_color));ds.setUnderlineText(false);}@Overridepublic void onClick(View widget) {}}, smrzSI, smrzSI+smrz.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);spannableString.setSpan(new ClickableSpan() {@Overridepublic void updateDrawState(TextPaint ds) {super.updateDrawState(ds);ds.setColor(activity.getResources().getColor(R.color.app_color));ds.setUnderlineText(false);}@Overridepublic void onClick(View widget) {RouterHelper.startWebView(activity, activity.getString(R.string.service_url));}}, zxkfSI, zxkfSI+zxkf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);return spannableString;}
防抖动
import android.os.SystemClock;public class FastClickInterceptor {private static final long MIN_INTERVAL = 1000;private long mLastClickTime;public boolean shouldIntercept() {if (SystemClock.elapsedRealtime() - mLastClickTime < MIN_INTERVAL) {return true;}mLastClickTime = SystemClock.elapsedRealtime();return false;}
}

Android 常用API自查表(一)相关推荐

  1. Android 常用API自查表(二)

    Android 常用API自查表 IQOO Neo6 日志授权 INSTALL_PARSE_FAILED_MANIFEST_MALFORMED 移除和拷贝assets中的文件 清空任务栈 Create ...

  2. android常用api大全,Android开发个人总结常用的api

    前言 这只是记录下开发过程中常用的api,是经常可能忘了导致去百度的 我还是希望大家最好记在脑子里,需要也提倡查找api,但我感觉只有记住了才能融会贯通,满足需求.每次查出来的,怕不了解,不敢修改等等 ...

  3. android常用api大全,Android API详解大全.pdf

    Android API详解大全 Android -- TextView 一.TextView的API 1.1 结构 java.lang.Object ↳ android.view.View ↳ and ...

  4. android常用api大全,Android相关常用API……

    android.provider.MediaStore里包含了相关的Image,Video,Audio信息,可通过managedQuery方法来查询和遍历. Android中的AdapterView使 ...

  5. 全面解读系统更新,收藏下这份 Android 12 (S) 版本适配自查表

    Android 12 是 2021 年 10 月发布的最新正式版本,然而很多同学表示还没有适配.针对开发者在进行版本适配过程中遇到的问题,我们建立了 GitHub · AndroidPlatformW ...

  6. Android 系统(78)---《android framework常用api源码分析》之 app应用安装流程

    <android framework常用api源码分析>之 app应用安装流程 <android framework常用api源码分析>android生态在中国已经发展非常庞大 ...

  7. 交叉表 列字段排序_百度App设计部:四步打造交互设计自查表

    UXD设计研究室 · 百度MEUX外部合作自媒体 设计自查是设计师常用的检验工具,经常以"自查表"形式呈现,可以帮助我们快速遍历设计方案,修正遗漏或不周.善用设计自查,不止可以避免 ...

  8. Android常用开源项目

    Android开源项目第一篇--个性化控件(View)篇   包括ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.Progre ...

  9. Android常用面试题大全

    1.TCP和UDP之间的区别?什么是URL ? TCP被称为用户数据报协议;UDP被称为信息传输控制协议;URL被称为统一资源定位符,通过统一资源定位符可以唯一定位到互联网上的某个资源(图片.视频.音 ...

最新文章

  1. 阿里、腾讯基本薪资曝光,资深算法工程师24万美元,高级研究员26万美元
  2. Wix 安装部署教程(十四) -- 多语言安装包之用户许可协议
  3. 领域模型驱动设计(Domain Driven Design)入门概述
  4. python中str用法_python中的str()不能直接用吗 -问答-阿里云开发者社区-阿里云
  5. nginx 强制跳转https_Nginx服务器环境手动安装Discuz! Q非详细教程
  6. 【HC资料合集】2019华为全联接大会主题资料一站式汇总,免费下载!
  7. 苹果A14芯片组件曝光,iPhone 12发布不远了?
  8. Visual Studio解决方案的目录结构设置和管理
  9. linux系统Vsftpd搭建FTP
  10. mysql pmm安装_PMM 安装部署
  11. 开天辟地-Go语言的见面仪式
  12. Linux 忘记密码解决方法
  13. 1/4-36UNS-2A的螺纹
  14. 工具推荐:JDownloader - 下载网盘资料的好工具
  15. 调整图片大小的方法(变大或变小)
  16. C语言解决找零钱问题
  17. 更省密令是什么?更省密令填什么
  18. 荣联科技转型的一二三四五
  19. 熵、条件熵、联合熵、互信息的理解
  20. 【数据集|COCO】COCO格式数据集制作与数据集参数计算

热门文章

  1. 一款小巧的鼠标增强软件:Smooze Pro for Mac
  2. 2023中国大学排名,软科发布
  3. matlab升压斩波仿真,升压斩波电路设计与仿真.doc
  4. OPENWRT 变砖处理
  5. 基于freeswitch的智能外呼1-自动外呼系统构建
  6. L1-082 种钻石
  7. 单片机开发-红外遥控芯片EN8F629
  8. iPhonexr安兔兔html5测试,iPhone XR 安兔兔跑分出炉!竟与 iPhone XS 相差无几
  9. Visual Studio 2019恢复默认界面
  10. 【CF1389】E. Calendar Ambiguity(数论)