Android开发百科全书③
Posted CodingForAndroid
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发百科全书③相关的知识,希望对你有一定的参考价值。
java.io.IOException: Cleartext HTTP traffic to xxx.xxx.xxx.xxx not permitted
https://blog.csdn.net/nidongde521/article/details/86496804
android9.0 默认是禁止所有的http
请求的,需要在代码中设置如下代码才可以正常进行网络请求: android:usesCleartextTraffic=“true”。
<application
android:name="xxxx.xxxx.xxx.xxx"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppBaseTheme"
android:usesCleartextTraffic="true">
更高得编译版本中 使用如上配置也不起作用,需要添加配置文(network_security_config.xml)件如下:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>
之后在application中添加配置如下,即可:
<application android:networkSecurityConfig="@xml/network_security_config" .>
RelativeLayout的子View alignParentBottom 和 marginBottom一起使用marginBottom无效.
当设置为android:layout_height="wrap_content"时,最下面的控件layout_marginBottom属性无效,如果其他控件使用layout_above让自己处于最下面的控件之上,那么layout_marginBottom属性有效。
当设置为android:layout_height="match_parent"时,或者高度为固定值,那么最下面的控件layout_marginBottom属性才会有效。
还可以用一个布局包裹起来,再使用marginBottom。
Android getBackground().setAlpha遇到问题解决办法
使用getBackground().setAlpha,导致其他布局背景透明度都改变的问题
从晚上9点就开始琢磨,为什么我在一个地方设置了getBackground().setAlpha(0);在别的activity中有些控件也变成透明的了,让我百思不得其解,
两个textview,background都指向相同的资源,那如果text1.getBackground().setAlpha(255)(不透明),那text2的背景是不是也跟着变成不透明的呢,答案是yes,那为什么呢:默认情况下,所有的从同一资源(R.drawable.***等等)加载的实例都共享一个共用的状态,如果你更改一个实例的状态,其余的实例都会接收到相同的通知。
那怎么解决这种情况呢,看看这个方法:
翻译一下注释吧:让这个drawable可变,这个操作是不可逆的。一个可变Drawable可以保证不与其它的Drawable分享一个状态。当你需要修改资源中的Drawable的属性时这个方法是非常有用的,因为默认情况下加载相同资源的所有Drawable实例拥有同一个状态,如果你在一个地方改变了状态,其它的实例也会跟着改变。
OK。所以
text1.getBackground().mutate().setAlpha(255);
//返回按钮样式,逐渐透明
ivTitleBack.setBackgroundResource(R.drawable.icon__round_back);
ivTitleBack.getBackground().mutate().setAlpha((int)( 255- alpha/2 * 255));
// 设置分享按钮样式
tvProductDetailShare.setBackgroundDrawable(ImageUtils.getStateListDrawable(getResources().getDrawable(R.drawable.icon_round_share), this));
tvProductDetailShare.getBackground().mutate().setAlpha((int)(255- alpha/2 * 255));
//标题背景透明度渐变
llHeaderTitleBar.getBackground().mutate().setAlpha((int)( alpha/2 * 255));
//标题文字透明度渐变
commentView.setTextColor(Color.argb((int)(255- alpha/2 * 255)/2, 64, 64, 65)); //文字透明度
productView.setTextColor(Color.argb((int)(255- alpha/2 * 255)/2, 64, 64, 65)); //文字透明度
//导航底部横线透明度渐变
tabIndicator.getBackground().mutate().setAlpha((int)( alpha/2 * 255));
Android 存储路径
Environment.getExternalStorageDirectory()
context.getExternalFilesDir(dir)
context.getExternalCacheDir()
ExternalCacheDir: /storage/emulated/0/Android/data/com.womai/cache
ExternalStorageDirectory: /storage/emulated/0
ExternalStorageState:mounted
context.getFilesDir()
context.getCacheDir()
getFilesDir: /data/user/0/com.womai/files
CacheDir: /data/user/0/com.womai/cache
ExternalCacheDir:/storage/emulated/0/Android/data/com.womai/cache
android 关于dialog全屏和非全屏设置
为了将dialog设置为全屏,我们经常在布局文件中将父控件宽高设置为math_parent,但是发现效果并没有像我们想象的实现全屏。甚至我们将style设置为true但是也并没有什么效果。下面说说我的方法吧,写的不好的地方,希望指正啊。
方法一:
dialog设置全屏方法一:获取屏幕的大小,然后设置dialog的宽高为屏幕的宽高。
Display display = getWindow().getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
//设置dialog的宽高为屏幕的宽高
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height);
setContentView(view, layoutParams)
方法二:
下面这行代码一定要放在setContentView(view);后面执行。layoutParams一定要设置为MATH_PARENT,同理,如果只是想将dialog设置为内容包裹,则将layoutParams设置为WRAP_CONTENT即可。
getWindow().setLayout((ViewGroup.LayoutParams.MATCH_PARENT), ViewGroup.LayoutParams.MATCH_PARENT);
监听横竖屏切换
1、AndroidManifest.xml中将activity 代码如下:
<activity
android:name="com.suma.smartview.activity.LTVDetailActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity>
2、代码里码如下:
public void onConfigurationChanged(Configuration newConfig)
super.onConfigurationChanged(newConfig);
//切换为竖屏
if (newConfig.orientation == Configuration .ORIENTATION_PORTRAIT)
else if (newConfig.orientation == Configuration .ORIENTATION_LANDSCAPE)
解决ViewPager使用setCurrentItem跨距离(中间间隔多个page页)切换过渡动画闪现问题
为什么我没有设置过渡动画,且只用了setCurrentItem(int item)方法却出现了这种情况?
setCurrentItem(int item)源码分析
/**
* Set the currently selected page. If the ViewPager has already been through its first
* 设置切换到当前选定页。如果ViewPager已经通过其与当前适配器的第一个布局
* layout with its current adapter there will be a smooth animated transition between
* 将有一个平滑的动画过渡当前item和指定item之间。
* the current item and the specified item.
*
* @param item Item index to select
*/
public void setCurrentItem(int item)
mPopulatePending = false;
setCurrentItemInternal(item, !mFirstLayout, false);
也就是说,ViewPager在通过其与当前适配器的第一个布局后,在当前item与指定item切换时,还是会存在一个平滑的过渡动画,这也是我们多页面切换时出现问题的病症所在,这里主要是由mFirstLayout来控制——源码中的mFirstLayout默认值为true,在onLayout方法中又变动其值为false.
setCurrentItem(int item, boolean smoothScroll)源码分析
那么如果使用ViewPager类中与setCurrentItem(int item)比较相似的setCurrentItem(int item, boolean smoothScroll)呢?我们先来看下它的源码:
/**
* Set the currently selected page.
* 设置切换到当前选择的页面
* @param item Item index to select 选定页面的下标
* @param smoothScroll True to smoothly scroll to the new item, false to transition immediately
* true:平滑滚动到新的item,false:立即滚动到指定位置.
*/
public void setCurrentItem(int item, boolean smoothScroll)
mPopulatePending = false;
setCurrentItemInternal(item, smoothScroll, false);
通过对setCurrentItem(int item, boolean smoothScroll)源码的分析,我们可以发现,当我们使用其代替setCurrentItem(int item)进行使用时,为了避免跨距离切换出现上述异常情况,我们只需要设置smoothScroll = false,关闭过渡动画即可解决。
解决方法
使用setCurrentItem(int item,boolean smoothScroll)方法
在跨距离切换的时候,使用setCurrentItem(position,false)方法来操作即可解决问题。
参数item:目标页的位置;
参数smoothScroll:是否平滑过渡(true:是,false:否)。
决ViewPager跨距离(中间间隔多个page页)切换过渡动画闪现问题
圆形圆角的几种实现方式
(一)自定义圆形圆角ImageView库地址
compile ‘com.makeramen:roundedimageview:2.3.0’
xml中属性:
riv_border_width: 边框宽度
riv_border_color: 边框颜色
riv_oval: 是否圆形
riv_corner_radius: 圆角弧度
riv_corner_radius_top_left:左上角弧度
riv_corner_radius_top_right: 右上角弧度
riv_corner_radius_bottom_left:左下角弧度
riv_corner_radius_bottom_right:右下角弧度
在xml布局中实现布局
<com.makeramen.roundedimageview.RoundedImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/avatar"
app:riv_border_color="#333333"
app:riv_border_width="2dp"
app:riv_oval="true" />
(二)Glide实现圆角、圆形图
用三方库 compile 'jp.wasabeef:glide-transformations:2.0.1’
Glide V3 实现圆图
Glide.with((Activity) t).load(url)
.bitmapTransform(new CropCircleTransformation((Activity) t))
.into(imageView);
Glide V3 实现圆角
Glide.with((Activity) t)
.load(url)
.dontTransform().
bitmapTransform(new RoundedCornersTransformation((Activity) t, cornerValue, 0, RoundedCornersTransformation.CornerType.ALL))
.into(imageView);
(三)自定义实现
public class MyRoundImageView extends ImageView
private int defaultRadius;
private int radius;
private int leftTopRadius;
private int rightTopRadius;
private int rightBottomRadius;
private int leftBottomRadius;
float width, height;
public MyRoundImageView(Context context)
this(context, null);
init(context, null);
public MyRoundImageView(Context context, AttributeSet attrs)
this(context, attrs, 0);
init(context, attrs);
public MyRoundImageView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
init(context, attrs);
private void init(Context context, AttributeSet attrs)
if (Build.VERSION.SDK_INT < 18)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
defaultRadius = SysUtils.dipToPx(context,6);
if(attrs!=null)
// 读取配置
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.Custom_Round_Image_View);
radius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_radius, defaultRadius);
leftTopRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_left_top_radius, defaultRadius);
rightTopRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_right_top_radius, defaultRadius);
rightBottomRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_right_bottom_radius, defaultRadius);
leftBottomRadius = array.getDimensionPixelOffset(R.styleable.Custom_Round_Image_View_left_bottom_radius, defaultRadius);
//如果四个角的值没有设置,那么就使用通用的radius的值。
if (defaultRadius == leftTopRadius)
leftTopRadius = radius;
if (defaultRadius == rightTopRadius)
rightTopRadius = radius;
if (defaultRadius == rightBottomRadius)
rightBottomRadius = radius;
if (defaultRadius == leftBottomRadius)
leftBottomRadius = radius;
array.recycle();
else
leftTopRadius = rightTopRadius = rightBottomRadius = leftBottomRadius = defaultRadius;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
super.onLayout(changed, left, top, right, bottom);
width = getWidth();
height = getHeight();
@Override
protected void onDraw(Canvas canvas)
//这里做下判断,只有图片的宽高大于设置的圆角距离的时候才进行裁剪
int maxLeft = Math.max(leftTopRadius, leftBottomRadius);
int maxRight = Math.max(rightTopRadius, rightBottomRadius);
int minWidth = maxLeft + maxRight;
int maxTop = Math.max(leftTopRadius, rightTopRadius);
int maxBottom = Math.max(leftBottomRadius, rightBottomRadius);
int minHeight = maxTop + maxBottom;
if (width >= minWidth && height > minHeight)
Path path = new Path();
//四个角:右上,右下,左下,左上
path.moveTo(leftTopRadius, 0);
path.lineTo(width - rightTopRadius, 0);
path.quadTo(width, 0, width, rightTopRadius);
path.lineTo(width, height - rightBottomRadius);
path.quadTo(width, height, width - rightBottomRadius, height);
path.lineTo(leftBottomRadius, height);
path.quadTo(0, height, 0, height - leftBottomRadius);
path.lineTo(0, leftTopRadius);
path.quadTo(0, 0, leftTopRadius, 0);
canvas.clipPath(path);
super.onDraw(canvas);
public void SetRoundValue(float radius)
leftTopRadius = rightTopRadius = rightBottomRadius = leftBottomRadius = defaultRadius = (int) radius;
invalidate();
attr.xml 注册属性
<declare-styleable name="Custom_Round_Image_View">
<attr name="radius" format="dimension"/>
<attr name="left_top_radius" format="dimension"/>
<attr name="right_top_radius" format="dimension"/>
<attr name="right_bottom_radius" format="dimension"/>
<attr name="left_bottom_radius" format="dimension"/>
</declare-styleable>
Suggestion: use tools:overrideLibrary="" to force usage
应用在Android Studio Build的时候,抛出了如下异常:
Error:Execution failed for task ‘:app:processInternalDebugManifest’.
Manifest merger failed : uses-sdk:minSdkVersion 11 cannot be smaller than version 14 declared in library [fm.jiecao:jiecaovideoplayer:4.5_preview1] E:\\workspace\\XWorld\\app\\build\\intermediates\\exploded-aar\\fm.jiecao\\jiecaovideoplayer\\4.5_preview1\\AndroidManifest.xml
Suggestion: use tools:overrideLibrary=“fm.jiecao.jcvideoplayer_lib” to force usage
错误原因:
出现这个错误的原因是我引入的第三方库最低支持版本高于我的项目的最低支持版本,异常中的信息显示:我的项目的最低支持版本为8(Android 2.2),而第三方库的最低支持版本为9(Android 2.3),所以抛出了这个异常。
解决办法:
在AndroidManifest.xml文件中 标签中添加,其中的xxx.xxx.xxx为第三方库包名,如果存在多个库有此异常,则用逗号分割它们,例如:,这样做是为了项目中的AndroidManifest.xml和第三方库的AndroidManifest.xml合并时可以忽略最低版本限制。
How do I use tools:overrideLibrary in a build.gradle file?
add <uses-sdk tools:overrideLibrary="android.support.v17.leanback"/>
don't forget to include
xmlns:tools="http://schemas.android.com/tools" too, before the <application> tag
过滤GA一些错误日志,不上报
重写ExceptionHandler .
/**
* GA 发送异常信息
*
* @param debugMode
*/
public void sendException(boolean debugMode)
if (debugMode)
return;
try
String deviceName = SysUtils.getSystemModel();
if (!TextUtils.isEmpty(deviceName) && deviceName.contains(Device_OPPO))
//用于分析TimeOut事件,是否由oppo r9 引起
return;
Tracker t = getGATracker(MyApp.TrackerName.APP_TRACKER);
Thread.UncaughtExceptionHandler myHandler = new NewExceptionReporter(
t,
Thread.getDefaultUncaughtExceptionHandler(),
getApplication());
// Make myHandler the new default uncaught exception handler.
Thread.setDefaultUncaughtExceptionHandler(myHandler);
catch (RuntimeException e)
return;
catch (Exception e)
return;
根据Thread 与 Exception类型区分,上不上报。
/**
* 重写 UncaughtExceptionHandler 过滤错误
* @date 2019-12-31
*/
public class NewExceptionReporter extends ExceptionReporter
public NewExceptionReporter(Tracker tracker, Thread.UncaughtExceptionHandler uncaughtExceptionHandler, Context context)
super(tracker, uncaughtExceptionHandler, context);
@Override
public void uncaughtException(Thread thread, Throwable throwable)
Log.e("uncaughtException",""+thread.getName()+" "+throwable.toString()+" "+(throwable instanceof ArithmeticException));
if (thread.getName().contains("Finalizer") && throwable instanceof ArithmeticException)
//ignore it
else
super.uncaughtException(thread, throwable);
欢迎爱学习的小伙伴加群一起进步:230274309 。 一起分享,一起进步!少划水,多晒干货!!欢迎大家!!!(进群潜水者勿加) |
以上是关于Android开发百科全书③的主要内容,如果未能解决你的问题,请参考以下文章