- View 点击不穿透
- ListView 在padding中绘制
- Dialog Style
- SpannableString
- 隐式 Intent
- onTaskRemoved
- implementation VS api
- 混淆
- Usb Device no permission
- 更改Project名
- 没有存储权限时的缓存
- 宽/高自适应Fresco
- 全机型16:9图片适应
- View的animate()使用
- AnimatorSet使用
- TextView去除上下空边距
- GridLayoutManager的坑
- 替换纯色图标的颜色
View 点击不穿透
如果有多层view叠加时,要使点击最上层view不穿透到下一层view。必需要让上层View消耗掉点击事件,也就是在OnTouchEvent
中return true
。
因为这样所有Touch
事件就都有点击的这个view处理了,不会上传到parentVew
。所以点击就不会穿透到parentView
了。
xml
代码如下:
android:clickable="true"
ListView 在padding中绘制
ListView
和ScrollView
滑动时可以在padding部分内绘制内容
android:clipToPadding="false"
Dialog Style
在/res/value/styles.xml
中写入,直接通过R.style.MyDialog
引用
<style name="MyDialog">
<item name="android:windowFrame">@null</item> <!-- 边框 -->
<item name="android:windowIsFloating">false</item> <!-- 是否浮现在activity之上 -->
<item name="android:windowIsTranslucent">false</item> <!-- 半透明 -->
<item name="android:windowNoTitle">true</item> <!-- 无标题 -->
<item name="android:windowBackground">@color/transparent</item> <!-- 背景透明 -->
<item name="android:windowContentOverlay">@null</item>
<item name="android:theme">@android:style/Theme.Dialog</item>
</style>
SpannableString
用SpannableString
使TextView
中的某部分字体改变颜色,或添加点击事件
- 改变颜色
SpannableString spannableString = new SpannableString(subTitle); spannableString.setSpan(new ForegroundColorSpan(color), index, lastInex + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); tvTextView.setText(spannableString);
- 部分文字添加点击事件
其他和改变颜色相似,只是setSpan
传入的第一个参数不同:spannableString.setSpan(new ClickableSpan(){...}, index, lastInex + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
使用
databinding
也可以使用SpannableString
,只要在ViewModel
里面返回的类型从String
改成SpannableString
就可以了。
隐式 Intent
隐式Intent
指的是:不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。
如启动activity
时:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, sendMsg);
sendIntent.setType("text/plain");
if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(sendIntent);
}
会弹出一个列表让你选择想要打开的应用,如短信等
如果你想要成为一个以上的一个过滤器:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
参考:https://developer.android.com/guide/components/intents-filters
onTaskRemoved
当service
关联的Task
被移除的时候,会调用如下接口:
public void onTaskRemoved(Intent rootIntent) {
}
如果app运行过程中开始了一个service
,当用户手动杀手app的时候,会回调这个接口,可以在里面处理一些事情。
Android O+
程序退后台之后,service
一分钟后会被杀,会失效。
参考:https://stackoverflow.com/questions/21040339/how-to-know-when-my-app-has-been-killed
implementation VS api
gradle
中使用implementation
和api
的区别主要体现在编译速度,和子引用可不可以在主项目中使用上(api
声明的主项目中可以用lib里面的引用库内容,而implementation
声明的不可以)。
参考文章:https://medium.com/mindorks/implementation-vs-api-in-gradle-3-0-494c817a6fa
混淆
Usb Device no permission
手机连接linux设备电脑,不能操作手机,或者android studio
安装设备时显示null
。
解决方法:
打开
sudo gedit /etc/udev/rules.d/51-android.rules
添加
SUBSYSTEM=="usb", ATTR{idVendor}=="USB_ID", MODE="0666", GROUP="plugdev"
USB_ID:这个值填lsusb
中显示的对应的设备的”:”前的4位数。如Huawei
是12d1
。
更改Project名
1、 先重命名目录,然后导入
2、 将*.iml
和其中内容中的老名字替换为新名字
3、 包目录上右键Refactor
,重新命名包名
没有存储权限时的缓存
getExternalFilesDir
这个在6.0
以上版本需要动态请求权限,而getCacheDir
这个不需要。
这两个都能获得缓存路径,路径有所不同:
getExternalFilesDir:/storage/emulated/** (用于长久储存)
getCacheDir: /data/user/**
宽/高自适应Fresco
public static void loadImageWithAutoHeight(final SimpleDraweeView view, String path, final int imgWidth, final int radius) {
LogUtil.d(Constants.TAG_V_525 +"path===" + path);
if (view == null) {
return;
}
ControllerListener<ImageInfo> controllerListener =
new ControllerListener<ImageInfo>() {
@Override
public void onSubmit(String s, Object o) {
}
@Override
public void onFinalImageSet(String s,
@Nullable ImageInfo imageInfo,
@Nullable Animatable animatable) {
if (imageInfo == null) {
LogUtil.e(Constants.TAG_V_525 + " error: imageInfo is null.");
return;
}
int height = imageInfo.getHeight();
int width = imageInfo.getWidth();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = imgWidth;
layoutParams.height =
(int) ((float)(imgWidth * height) / (float) width);
view.setLayoutParams(layoutParams);
if (radius > 0) {
RoundingParams roundingParams =
RoundingParams.fromCornersRadius(radius);
view.getHierarchy().setRoundingParams(roundingParams);
}
}
@Override
public void onIntermediateImageSet(String s,
@Nullable ImageInfo imageInfo) {
}
@Override
public void onIntermediateImageFailed(String s,
Throwable throwable) {
}
@Override
public void onFailure(String s, Throwable throwable) {
}
@Override
public void onRelease(String s) {
}
};
Uri uri = Uri.parse(path);
view.setController(Fresco
.newDraweeControllerBuilder()
.setControllerListener(controllerListener)
.setUri(uri)
.build());
}
全机型16:9图片适应
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) itemView.getLayoutParams();
ViewGroup parentView = (ViewGroup) itemView.getParent();
int padding = ViewUtils.dip2px(10); // GridView 纵向 Padding, 同 ae_camera_video_story_play_page_view.xml 中的数值;
int itemWidth = ViewUtils.getScreenWidth() - padding * 2;
int itemHeight = parentView.getHeight() - padding;
if (itemWidth * 16 / 9 > itemHeight) {
itemWidth = itemHeight * 9 / 16;
} else {
itemHeight = itemWidth * 16 / 9;
}
layoutParams.width = itemWidth;
layoutParams.height = itemHeight;
padding += (parentView.getWidth() - itemWidth - padding * 2) / 2; // GridView两边的padding
if (Log.isDevelopLevel()) {
Log.d(TAG, QLog.DEV, "one itemHeight " + itemHeight + " itemWidth: " + itemWidth +
" screenWidth: " + ViewUtils.getScreenWidth() + " viewWidth: " + parentView.getWidth() + " padding: " + padding);
}
itemView.setLayoutParams(layoutParams);
parentView.setPadding(padding, 0, 0, 0);
View的animate()使用
vAnimView.animate().setDuration(200).alpha(0f).start();
可以通过设置时间+动画类型直接开始
AnimatorSet使用
AnimatorSet animatorSet = new AnimatorSet();
ValueAnimator text1AppearAni = ValueAnimator.ofInt(10, 0);
text1AppearAni.setDuration(1000);
text1AppearAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
});
ValueAnimator text2AppearAni = ValueAnimator.ofInt(-22, 0);
text2AppearAni.setDuration(1000);
text2AppearAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
});
ValueAnimator dismissAni = ValueAnimator.ofFloat(0f, 1f);
dismissAni.setDuration(1000);
dismissAni.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
}
});
//串联动画
animatorSet.play(text1AppearAni)
.with(text2AppearAni)
.with(resultDividerAppearAni)
.before(dismissAni);
TextView去除上下空边距
android:includeFontPadding=”false”
GridLayoutManager的坑
GridLayoutManager + RecyclerView在调用notifyItemChange的时候会刷新回顶部 解决方案: gridLayoutManager.setAutoMeasureEnabled(false);
参考:https://stackoverflow.com/questions/36724898/notifyitemchanged-make-the-recyclerview-scroll-and-jump-to-up
替换纯色图标的颜色
view.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN)