飞道的博客

Android开发百科全书③

488人阅读  评论(0)

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 。 一起分享,一起进步!少划水,多晒干货!!欢迎大家!!!(进群潜水者勿加)

转载:https://blog.csdn.net/u011733020/article/details/103521747
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场