浅析onWindowsFocusChanged()方法

节选自:浅析onWindowsFocusChanged()方法


概述

从字面上来讲,onWindowsFocusChanged()方法是指当窗口焦点变化的时候;从意义来说,onWindowsFocusChanged()就是指当前的Activity的Windows(窗口)获取或者失去焦点时这个方法就会被调用,并且当回调这个方法时,Activity是完全可见的。

在Activity生命周期中,onStart(), onResume(), onCreate()都不是布局visible的时间点,真正的visible时间点是onWindowFocusChanged()函数被执行时。从onWindowFocusChanged()被执行起,用户可以与应用进行交互了,换句话说,如果你想要在Activity加载后做些操作,可以在这个方法里调用而这之前,对用户的操作需要做一点限制。

onWindowFocusChanged()的使用情景与作用

根据介绍可以了解,onWindowFocusChanged()使用于以下等情景:

  1. 首次进入一个Activity后会在onResume()方法后面调用;
  2. 从Activity 跳到另一个Activity,新的窗口会获取焦点, 旧的Activity的窗口会失去焦点;
  3. 应用进入后台,窗口失去焦点;
  4. 应用从后台返回当前, 窗口重新获取焦点;

因此其可以有如下作用:

  1. 监控一个Activity是否载完毕;
  2. 在Activity加载后进行一些操作,如获取手机屏幕的高度和宽度;
  3. 当Activity挂起或恢复时,可以在方法内进行一些数据的保存或恢复的操作;

【转】如何实现TextureView或者SurfaceView 预览框为圆角

转载自:如何实现TextureView或者SurfaceView 预览框为圆角


项目中,视频预览界面框为圆角;但发现是使用的Renderer渲染的方法进行的,的确可以有圆角效果。

但有个问题是:我的视频源与要显示视频的预览框的长宽比率不同,预览框需要满屏看到视频源,如果不做处理,视频源只能通过压缩来显示。造成了视频的变形,如果不拉伸处理,那么就进行裁剪处理,需要对视频进行Matrix操作,如移动,伸缩处理。进行这些处理后,渲染的圆角效果就不再出现了。所以通过Renderer来进行圆角效果,不但复杂而且并不可靠。

通过网上的搜索可以找到Android5.0后,一个类ViewOutlineProvider;基于View自身的setClipToOutline(boolean clipToOutline)和setOutlineProvider(ViewOutlineProvider provider)方法实现了该需求。

import android.graphics.Outline;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewOutlineProvider;

public class TextureVideoViewOutlineProvider extends ViewOutlineProvider {
    private float mRadius;

    public TextureVideoViewOutlineProvider(float radius) {
        this.mRadius = radius;
    }

    @Override
    public void getOutline(View view, Outline outline) {
        Rect rect = new Rect();
        view.getGlobalVisibleRect(rect);
        int leftMargin = 0;
        int topMargin = 0;
        Rect selfRect = new Rect(leftMargin, topMargin,
                rect.right - rect.left - leftMargin, rect.bottom - rect.top - topMargin);
        outline.setRoundRect(selfRect, mRadius);
    }
}
 mView.setOutlineProvider(new TextureVideoViewOutlineProvider(radius));
 mView.setClipToOutline(true);

任何View都可通过此方法达到圆角效果。

Android自定义拍照实现

节选自:Android自定义拍照实现


/**
 * 注释:拍照并保存图片到相册
 * 时间:2019/3/1 0001 15:37
 * 作者:郭翰林
 */
private void takePhoto() {
    isTakePhoto = true;
    //调用相机拍照
    mCamera.takePicture(null, null, null, (data, camera1) -> {
        //视图动画
        mPhotoLayout.setVisibility(View.GONE);
        mConfirmLayout.setVisibility(View.VISIBLE);
        AnimSpring.getInstance(mConfirmLayout).startRotateAnim(120, 360);
        imageData = data;
        //停止预览
        mCamera.stopPreview();
    });
}

使用TextView替代Button,使用ImageView替代ImageButton

Button继承自TextView,ImageButton继承自ImageView。

<TextView
    android:id="@+id/nextBtn"
    android:layout_width="250dp"
    android:layout_height="80dp"
    android:background="@drawable/bg_0062ec_40"
    android:gravity="center"
    android:text="下一步"
    android:textColor="#FFFFFF"
    android:textSize="34sp" />
<ImageView
    android:id="@+id/backBtn"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:scaleType="center"
    app:srcCompat="@drawable/icon_back" />

【转】Android中TextView与Button的区别

转载自:Android中TextView与Button的区别


Button继承于TextView,一般情况下,TextView用来承载静态文本,Button用来响应点击事件。但是TextView 继承自View,点击事件是从View就有的特性,所以TextView也能点击。那么TextView与Button有什么不同呢?

1.TextView中文字默认是从左上方开始,Button中文字默认是居中显示

2.TextView默认背景透明,Button默认背景灰色的

3.TextView点击无效果,Button默认状态下点击变黄色(它有一个默认的背景选择器)

4.TextView默认不拦截点击事件,Button会拦截点击事件(比如说我们一个ListView,Item的布局中有一个TextView和Button,我们在这个TextView上点击会触发ListView的OnItemClickListener方法,在Button上点击并不会触发ListView的OnItemClickListener方法,因为Button把这个点击事件拦截了)。

Android Context完全解析

节选自:Android Context完全解析,你所不知道的Context的各种细节


Context一共有三种类型,分别是Application、Activity和Service。

Context数量 = Activity数量 + Service数量 + 1

上面的1代表着Application的数量,因为一个应用程序中可以有多个Activity和多个Service,但是只能有一个Application。

Application单例模式:

public class MyApplication extends Application {

    private static MyApplication app;

    public static MyApplication getInstance() {
        return app;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        app = this;
    }
}

gRPC请求中对header进行处理

节选自:gRPC请求中对header进行处理


1.[Android (Java)]

1.1只设置客户端请求时附带的header

见类 io.grpc.stub.MetadataUtils,其中有个方法:

/**
 * Attaches a set of request headers to a stub.
 *
 * @param stub to bind the headers to.
 * @param extraHeaders the headers to be passed by each call on the returned stub.
 * @return an implementation of the stub with {@code extraHeaders} bound to each call.
 */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1789")
public static <T extends AbstractStub<T>> T attachHeaders(
        T stub,
        final Metadata extraHeaders) {
    return stub.withInterceptors(newAttachHeadersInterceptor(extraHeaders));
}

稍微自己封装一下的效果,如下:

private static <T extends AbstractStub<T>> T attachHeaders(T stub, final Map<String, String> headerMap) {
    Metadata extraHeaders = new Metadata();
    if (headerMap != null) {
        for (String key : headerMap.keySet()) {
            Metadata.Key<String> customHeadKey = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
            extraHeaders.put(customHeadKey, headerMap.get(key));
        }
    }
    return MetadataUtils.attachHeaders(stub, extraHeaders);
}