ZhuHuDaily问题
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。
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.pngWindow.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字符串。