ZhuHuDaily问题

字数 1079阅读 59

Android小Demo遇到的问题

在开发中遇到的问题:

  • ImageView属性,adjustViewBounds,scaleType
  • Window.setFlags
  • 状态栏着色
  • 通过File对象获取path
  • Activity.overaridePaddingTransition()

ImageView属性

adjustViewBounds

调整ImageView的界限来保持图像纵横比不变。

XML定义里的android:adjustViewBounds="true"会将这个ImageView的scaleType设为fitCenter。不过这个fitCenter会被后面定义的scaleType属性覆盖(如果定义了的话),除非在Java代码里再次显示调用setAdjustViewBounds(true)。

设置该属性无效的情况:

  • 如果设置的layout_width与layout_height都是定值,那么设置adjustViewBounds是没有效果的,ImageView将始终是设定的定值的宽高。
  • 如果设置的layout_width与layout_height都是wrap_content,那么设置adjustViewBounds是没有意义的,因为ImageView将始终与图片拥有相同的宽高比(但是并不是相同的宽高值,通常都会放大一些)。

实现属性效果,如果两者中一个是定值,一个是wrap_content,比如layout_width="100px",layout_height="wrap_content"时,ImageView的宽将始终是100px,而高则分两种情况:

  • 当图片的宽小于100px时,layout_height将与图片的高相同,即图片不会缩放,完整显示在ImageView中,ImageView高度与图片实际高度相同。图片没有占满ImageView,ImageView中有空白。
  • 当图片的宽大于等于100px时,此时ImageView将与图片拥有相同的宽高比,因此ImageView的layout_height值为:100除以图片的宽高比。比如图片是500X500的,那么layout_height是100。图片将保持宽高比缩放,完整显示在ImageView中,并且完全占满ImageView。

参考自博文ImageView的android:adjustViewBounds属性

scaleType

该属性值由一下几种可以选择:

  • matrix,绘制时,使用图像矩阵方式缩放。图像矩阵可以通过 setImageMatrix(Matrix) 设置。
  • fitXY,横向、纵向独立缩放,以适应该ImageView。
  • fitCenter,保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央。
  • fitStart,保持纵横比缩放图片,并且将图片放在ImageView的左上角。
  • fitEnd,保持纵横比缩放图片,缩放完成后将图片放在ImageView的右下角。
  • center,把图片放在ImageView的中央,但是不进行任何缩放。
  • centerInside,保持纵横比缩放图片,以使得ImageView能完全显示该图片。
  • centerCrop,保持纵横比缩放图片,以使图片能完全覆盖ImageView。

这里有一个属性值比较有疑问,于是写了一个例子来实践下:

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="android.example.com.imageviewusage.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Scale Type Specify Matrix"
        android:textSize="16sp"/>

    <ImageView
        android:id="@+id/id_img_matrix"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scaleType="matrix"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Scale Type Default Center"
        android:textSize="16sp"/>

    <ImageView
        android:id="@+id/id_img_center"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:scaleType="matrix"/>
</LinearLayout>

Java

private void initView() {
        mImgMatrix = (ImageView) findViewById(R.id.id_img_matrix);
        mImgCenter = (ImageView) findViewById(R.id.id_img_center);

        Matrix matrix = new Matrix();
        matrix.setTranslate(30, 20);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(), R.drawable.start, options);

        Bitmap bitmap = ScaleBitmap.scaleBitmap(options, this);
        
        mImgCenter.setImageBitmap(bitmap);
        mImgMatrix.setImageMatrix(matrix);
        mImgMatrix.setImageBitmap(bitmap);
    }

分析:在这里我对其中一个ImageView设定了指定的平移矩阵,并且效果确实和按照默认的图像矩阵绘制图片有区别。

效果

ScaleType Matrix.png

Window.setFlags

由于调用该方法的Activity是一个SplashActivity,所以我们需要实现Activity的全屏:没有ActionBar,没有标题栏,以及隐藏状态栏。

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_splash);
        initView();
    }

有一点需要注意,官方文档指出:Note that some flags must be set before the window decoration is created (by the first call to setContentView(View, android.view.ViewGroup.LayoutParams) or getDecorView(): FLAG_LAYOUT_IN_SCREEN and FLAG_LAYOUT_INSET_DECOR. These will be set for you based on the windowIsFloating attribute. 意思大概是要在setContentView()之前调用setFlags()。

setFlags()与addFlags()区别

addFlags()源码:

public void addFlags(int flags) {  
        setFlags(flags, flags);  
}  

其实两者可以这样等价:

this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
            WindowManager.LayoutParams.FLAG_FULLSCREEN);  

等价于:

this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

setFlags()可以实现多种效果

getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

可以实现窗体背景模糊

参考自博文UI效果(1):实现Activity全屏

个人理解

通过设置Window.setFlags()来实现Activity的全屏就是为了隐藏状态栏,实现状态栏沉浸的效果。

通过File获取路径

有两种方法可以获取File的路径:getAbsolutePath(),getPath.

getAbsolutePath()

返回File对象表示的完整的绝对文件名或目录名。这里不管创建FIle对象时用的是相对文件名还是绝对文件名,它都会返回整个完整的路径。

getPath()

返回File对象表示的完整的路径名和文件名。这里返回的就是创建FIle对象时,传递给构造函数的path/file_name字符串。

Activity.overaridePaddingTransition()

推荐阅读更多精彩内容