Android日常记录
App打开微信小程序
public static void openWxPath(Context context, String wxPath) {
IWXAPI api = WXAPIFactory.createWXAPI(context, Config.APP_ID);
WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
req.userName = "xxx"; // 填小程序原始id
req.path = wxPath;//拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
//可选打开 开发版,体验版和正式版
req.miniprogramType = IS_DEBUG ? WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_TEST :
WXLaunchMiniProgram.Req.MINIPTOGRAM_TYPE_RELEASE;
api.sendReq(req);
}
复制到粘贴板
ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
ClipData mClipData = ClipData.newPlainText("Label", rawResult.getText());
cm.setPrimaryClip(mClipData);
隐士启动
隐式启动Activity需要加这个判断
if(intent.resolve(context.getPackageManager))!=null){
//
}
App启动白屏
设置Theme
<style name="MNoActionBar" parent="Theme.AppCompat.NoActionBar">
<!--<item name="android:windowFullscreen">false</item>-->
<!--<item name="android:windowBackground">@drawable/welcome</item>//此行可以给window设置背景图片,单独设置此项不设置透明的话是没有延迟打开的情况(无白屏切换,和启动页使用同一资源则无缝切换,但默认是全屏的)-->
<item name="android:windowIsTranslucent">true</item>//设置透明之后不会有和页面背景图之间色值的闪烁,同时点击桌面图标时会有些延迟进入页面
</style>
activity中全屏启动图的时候,需要等到内容加载完成再调用全屏
private void setFullScreenEnable(boolean isEnable) {
if (isEnable) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //隐藏状态栏
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); //显示状态栏
}
}
打开应用市场
打开已安装的APP或跳转到应用市场进行安装
/**
* 跳转到已安装的APP,如果没有的话打开应用市场
*
* @param context 上下文
* @param appName 应用包名
*/
public static void openInstallApp(Context context, String appName) {
PackageInfo packageInfo = null;
PackageManager pm = context.getPackageManager();
try {
packageInfo = pm.getPackageInfo(appName, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
if (packageInfo != null) {//应用已安装
context.startActivity(pm.getLaunchIntentForPackage(appName));
} else {
Uri uri = Uri.parse("market://details?id=" + appName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Exception e) {
//"应用未安装"
}
}
}
View的测量模式
//以测量宽度为例,高度也是相似的处理
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int width = 0;
if(widthMode == MeasureSpec.EXACTLY){//指定大小的情况下
width = widthSize;
}else {
//int needWidth = measureWidth();
// 想要支持Padding
int needWidth = measureWidth() + getPaddingLeft() + getPaddingRight();
if(widthMode == MeasureSpec.AT_MOST){//最大不超过父控件的宽度
width = Math.min(needWidth, widthSize);
}else { //MeasureSpec.UNSPECIFIED 无限制
width = widthSize;
}
}
LayoutInflater
View view = LayoutInflater.from(this).inflate(R.layout.xx,null);
Dialog dialog = new Dialog(this);
dialog中如果需要设置宽和高的话,需要另外指定View根布局的LayoutParams属性,在inflate的过程中会解析xml布局为view,但是不会产生LayoutParams的属性。需要自己重新进行设定属性才能进行使用。源代码中有如下内容:
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
...
final Context inflaterContext = mContext;
final AttributeSet attrs = Xml.asAttributeSet(parser);
...
View result = root;//你传递的root
try {
...
if (TAG_MERGE.equals(name)) {//根布局是merge
if (root == null || !attachToRoot) {
throw new InflateException("<merge /> can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
//重新渲染布局
rInflate(parser, root, inflaterContext, attrs, false);
} else {
// Temp is the root view that was found in the xml
final View temp = createViewFromTag(root, name, inflaterContext, attrs);
ViewGroup.LayoutParams params = null;
if (root != null) {
// Create layout params that match root, if supplied
params = root.generateLayoutParams(attrs);
if (!attachToRoot) {
// Set the layout params for temp if we are not
// attaching. (If we are, we use addView, below)
temp.setLayoutParams(params);
}
}
...
// We are supposed to attach all the views we found (int temp)
// to root. Do that now.
if (root != null && attachToRoot) {
root.addView(temp, params);
}
// Decide whether to return the root that was passed in or the
// top view found in xml.
if (root == null || !attachToRoot) {
result = temp;
}
}
}
...
return result;
}
}
SpannableStringBuilder VS SpannableString
两者的区别和StringBuilder与String类似,使用方式一致。当我们在自定义TextView的字体样式的时候,需要用到这些,比如
- RelativeSizeSpan 调整指定位置的字体大小
- AbsoluteSizeSpan 设置指定位置的字体绝对大小,true时标准是dp,false是px
- ForegroundColorSpan 调整指定位置的字体颜色
- BackgroundColorSpan 调整指定位置的背景颜色
- ClickableSpan 指定位置可点击,需要自己处理点击事件,需要辅助
setMovementMethod(LinkMovementMethod.getInstance())来实现 - URLSpan 超链接效果
- MaskFilterSpan 字体效果展示,有EmbossMaskFilter和BlurMaskFilter
- StyleSpan 文字的样式调整
- UnderLineSpan 文字下划线
- StrikethroughSpan 文字删除线
- SuperscriptSpan 设置指定文字上标,类似数字的平方指数
- SubscriptSpan 设置指定文字下标
- ImageSpan 设置图片
SpannableString几个参数的意义
- what:对SpannableString进行润色的各种Span;
- int:需要润色文字段开始的下标;
- end:需要润色文字段结束的下标;
- flags:决定开始和结束下标是否包含的标志位,有四个参数可选
- SPAN_EXCLUSIVE_EXCLUSIVE:前后都不包括,即在指定范围的前面和后面插入新字符都不会应用新样式
- SPAN_EXCLUSIVE_INCLUSIVE:前面不包括,后面包括。即仅在范围字符的后面插入新字符时会应用新样式
- SPAN_INCLUSIVE_EXCLUSIVE:前面包括,后面不包括
- SPAN_INCLUSIVE_INCLUSIVE:前后都包括
TextView 的 maxLength vs maxEms
- maxLength是控制文本展示的长度,实际是调用通过文本的通过filters
setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
- maxEms 控制一行展示文本的宽度,宽度的标准是英文M字母在屏幕的宽度
LiveData的postValue 和 setValue
- setValue 只能在主线程调用,同步更新数据
- postValue 可在后台线程调用,其内部会切换到主线程调用 setValue,当连续调用 postValue 时,有可能只会收到最后一次数据更新通知。
字符串拼接的方式
| 拼接方式 | 次数 | 耗时 |
|---|---|---|
| str += newStr; | 10000 | 968ms |
| str = str + newStr | 10000 | 973ms |
| str.concat(newStr) | 10000 | 2ms |
| stringBuffer.append(newStr); | 10000 | 0ms |
| stringBuilder.append(newStr); | 10000 | 1ms |

浙公网安备 33010602011771号