android 小知识点

1.模拟返回按键(返回的比较慢)

try {
    Runtime.getRuntime().exec("input keyevent " + KeyEvent.KEYCODE_BACK);
} catch (IOException e) {
    e.printStackTrace();
}

2.检测当前网络状态

	/**
     * 检测当前网络状态
     * @param context
     * @return
     */
    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo info = connectivity.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                // 当前网络是连接的
                if (info.getState() == NetworkInfo.State.CONNECTED) {
                    // 当前所连接的网络可用
                    return true;
                }
            }
        }
        return false;
    }

3.复制文本

ClipboardManager cm = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData mClipData = ClipData.newPlainText("Label", "要复制的文字");
        cm.setPrimaryClip(mClipData);

4.设置字体不随系统字体更改

	@Override
    public Resources getResources() {
        Resources res = super.getResources();
        Configuration config = new Configuration();
        config.setToDefaults();
        res.updateConfiguration(config, res.getDisplayMetrics());
        return res;
    }

5.Activity重载自己可用于无网络页面重新加载(注意:不能是最后一个Activity不然会有动画)

startActivity(new Intent(Main2Activity.this, Main2Activity.class));
overridePendingTransition(0, 0);
finish();

6.BuildConfig类

参考自:http://blog.csdn.net/lvxiangan/article/details/71601451
BuildConfig类是一个根据build.gradle配置文件自动生成的类,有点类似于R.class,生成后不能修改

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.sign.demo";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "1.0";
}

可用BUILD_TYPE属性进行版本查看、DEBUG属性日志控制等
BUILD_TYPE debug(测试包) release(正式包)
DEBUG true (测试包) false(正式包)可用此属性管理日志数据

7.MessageFormat格式化字符串

参考自:http://www.cnblogs.com/fjdingsd/p/5143625.html
这里只使用了最简单的占位符的使用方法:

public class MainActivity extends AppCompatActivity {
    int max = 100;
    int now = 0;
    private TextView tvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvContent = findViewById(R.id.tv_content);
        final String format = "照片上传中... {0}/{1}";
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                now++;
                if (now < max) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
	                        //now max会替换掉{}中的0,1
                            tvContent.setText(MessageFormat.format(format, now, max));
                        }
                    });
                }
            }
        }, 0, 2000);
    }
}

8.android 热启动 冷启动

参考自:https://www.cnblogs.com/xunzhi/p/5794793.html

  • 冷启动:当启动应用时,后台没有该应用的进程,系统会重新创建一个新的进程分配给该应用。因为系统会重新创建一个新的进程分配给该应用,所以会先创建和初始化application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制)最后显示到界面上
  • 热启动:当启动应用时,后台已有应用的进程(例如:按back键、home键应用虽然会退出,但是该应用的进程依然保留在后台,可通过任务列表查看)。因为热启动是从已有的进程中启动,所以不会重新创建和初始化application,而只是重新创建和初始化MainActivity(测量、布局、绘制)
    因为一个应用从进程的创建到销毁,application只会初始化一次

9.去掉ScrollView、RecyclerView、ViewPager等可滑动控件,滑动到边缘的光晕效果

android:overScrollMode="never"

10.android:descendantFocusability

项目中RecyclerView条目中包含EditText时,由于EditText自动抢占焦点导致自动滚动的问题
给RecyclerView设置 android:descendantFocusability="beforeDescendants"
此属性作用为:定义此ViewGroup与子视图的焦点归属
此属性的值有三种:

  • beforeDescendants viewgroup会优先其子类控件而获取到焦点
  • afterDescendants viewgroup只有当其子类控件不需要获取焦点时才获取焦点
  • blocksDescendants viewgroup会覆盖子类控件而直接获得焦点

recyclerview包含WebView时,点击WebView会滑动到顶部,刷新数据时也会抢占焦点
recyclerview设置:android:descendantFocusability="blocksDescendants"
11.view.getLocationInWindow(int[])

获得当前view在窗口中的坐标
传入的参数int[] leftTop = {0 , 0}
调用后leftTop[0]为在窗口中left坐标
leftTop[1]为在窗口中top坐标
区分view.getLeft() view.getTop是针对于父视图的相对位置

判断点击的位置是否在某view中

public boolean isInBottomLayout(MotionEvent event) {
        if (bottom_layout != null) {
            int[] leftTop = {0, 0};
            //获取bottom_layout当前的location位置
            bottom_layout.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + bottom_layout.getHeight();
            int right = left + bottom_layout.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击在bottomlayout内,保留事件
                return false;
            } else {
                return true;
            }
        }
        return false;
    }

12.优化点击应用图标响应速度

https://blog.csdn.net/old_land/article/details/79708179?utm_source=blogxgwz8

		<item name="android:windowNoTitle">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowBackground">@drawable/welcome_pic</item>
        <item name="android:windowFullscreen">true</item>

13.从全屏页面(见12条设置)跳转到非全屏页面,由于状态栏由不可见到可见,引起很明显的界面下移

参考:https://www.jianshu.com/p/63bba2e09b78
效果可以看:https://blog.csdn.net/u013011318/article/details/48296869
他的判断感觉写反了,而且不太好用if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
我的做法是

  • 在启动页的setcontentview方法之前,设置透明状态栏(因为启动页是全屏,状态栏不会显示)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//透明状态栏
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window window = getWindow();
    window.setFlags(
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
  • 在跳转到应用主页之前,切换到非全屏状态,状态栏会显示出来,但因为是透明状态栏,布局会拓展到系统栏的后面,跳转时只是把状态栏显示出来,并不会让布局发生下移

透明状态栏,布局会拓展到系统栏的后面:https://blog.csdn.net/QQxiaoqiang1573/article/details/79888186

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

或者


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

14.allowBackup属性

manifest中application节点allowBackup属性默认为true,允许通过adb backup对打开USB调试的设备进行数据备份,但会引起信息泄漏问题,详见 https://blog.csdn.net/yanbober/article/details/46417531

15.关于android LayoutInflater加载view的几个方法

参考:https://www.jb51.net/article/82620.htm

inflate(layoutId,null)–>调用inflate(layoutId,null,false) 返回子view,无param
inflate(layoutId,parent)–>调用inflate(layoutId,parent,true) 同最后一个,返回parent,子view被添加到parent中,携带param
inflate(layoutId,null,true/false) 返回子view,无param
inflate(layoutId,parent,false) 返回子view,携带param
inflate(layoutId,parent,true) 返回parent,子view被添加到parent中,携带param

代码如下:

LayoutInflater layoutInflater = LayoutInflater.from(this);
LinearLayout llMain = findViewById(R.id.ll_main);
View view1 = layoutInflater.inflate(R.layout.button, null);
View view2 = layoutInflater.inflate(R.layout.button, llMain);
View view3 = layoutInflater.inflate(R.layout.button, null, false);
View view4 = layoutInflater.inflate(R.layout.button, null, true);
View view5 = layoutInflater.inflate(R.layout.button, llMain, false);
View view6 = layoutInflater.inflate(R.layout.button, llMain, true);
/**
 *结果:
 * view1 button null null
 * view2 llMain FrameLayout.param FrameLayout (== view6)
 * view3 button null null
 * view4 button null null
 * view5 button LinearLayout.param null
 * view6 llMain FrameLayout.param button
 */
Log.d(TAG, "view1 = " + view1 + "view1  layoutParams = " + view1.getLayoutParams() + "view.getParent = " + view1.getParent());
Log.d(TAG, "view2 = " + view2 + "view2  layoutParams = " + view2.getLayoutParams() + "view.getParent = " + view2.getParent());
Log.d(TAG, "view3 = " + view3 + "view3  layoutParams = " + view3.getLayoutParams() + "view.getParent = " + view3.getParent());
Log.d(TAG, "view4 = " + view4 + "view4  layoutParams = " + view4.getLayoutParams() + "view.getParent = " + view4.getParent());
Log.d(TAG, "view5 = " + view5 + "view5  layoutParams = " + view5.getLayoutParams() + "view.getParent = " + view5.getParent());
Log.d(TAG, "view6 = " + view6 + "view6  layoutParams = " + view6.getLayoutParams() + "view.getChildAt(0) = " + ((ViewGroup) view6).getChildAt(0));

日志:

view1 = android.support.v7.widget.AppCompatButton{4268d70 VFED..C.. ......I. 0,0-0,0}view1  layoutParams = nullview.getParent = null
view2 = android.widget.LinearLayout{82288e9 V.E...... ......I. 0,0-0,0 #7f07004e app:id/ll_main}view2  layoutParams = android.widget.FrameLayout$LayoutParams@9a1796eview.getParent = android.support.v7.widget.ContentFrameLayout{5d4680f V.E...... ......I. 0,0-0,0 #1020002 android:id/content}
view3 = android.support.v7.widget.AppCompatButton{dbf109c VFED..C.. ......I. 0,0-0,0}view3  layoutParams = nullview.getParent = null
view4 = android.support.v7.widget.AppCompatButton{611caa5 VFED..C.. ......I. 0,0-0,0}view4  layoutParams = nullview.getParent = null
view5 = android.support.v7.widget.AppCompatButton{1efbe7a VFED..C.. ......I. 0,0-0,0}view5  layoutParams = android.widget.LinearLayout$LayoutParams@b79762bview.getParent = null
view6 = android.widget.LinearLayout{82288e9 V.E...... ......I. 0,0-0,0 #7f07004e app:id/ll_main}view6  layoutParams = android.widget.FrameLayout$LayoutParams@9a1796eview.getChildAt(0) = android.support.v7.widget.AppCompatButton{4fa9a88 VFED..C.. ......I. 0,0-0,0}

16.java格式化double数据 千分符和小数点互换(千分符是’.’ 小数点是’,’)

DecimalFormatSymbols decimalSymbols = DecimalFormatSymbols.getInstance();
decimalSymbols.setDecimalSeparator(',');
decimalSymbols.setGroupingSeparator('.');
DecimalFormat df = new DecimalFormat("###,###.00",
        decimalSymbols);
String format = df.format(2999999999999.115);

==>

2.999.999.999.999,12

17.shouldOverrideUrlLoading(WebView view, WebResourceRequest request)未拦截到请求

shouldOverrideUrlLoading(WebView view, String url)方法在7.0之后被废弃
shouldOverrideUrlLoading(WebView view, WebResourceRequest request)方法则是在7.0之后添加的
所以我们想要拦截某个请求时就需要重写这两个方法,之前没太注意这里,只重写了shouldOverrideUrlLoading(WebView view, WebResourceRequest request)方法,导致6.0的请求未被拦截。

https://stackoverflow.com/questions/36484074/is-shouldoverrideurlloading-really-deprecated-what-can-i-use-instead

18.改变阴影的深浅度

给控件添加阴影的方法一般是改变控件的elevation属性,直接设置的阴影设计觉得有点重。。。
改后的效果如下:
在这里插入图片描述
代码:
两个控件xml中属性一致,不过在代码中对阴影的透明度做了修改

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:background="@drawable/shape_solid_white_radius_10"
    android:elevation="3dp"
    android:padding="20dp"
    android:text="测试" />
<TextView
    android:id="@+id/tv_light"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:background="@drawable/shape_solid_white_radius_10"
    android:elevation="3dp"
    android:padding="20dp"
    android:text="测试" />
ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
    @Override
    public void getOutline(View view, Outline outline) {
        outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), ScreenUtils.dp2px(MainActivity.this, 10));
        outline.setAlpha(0.5f);
    }
};
findViewById(R.id.tv_light).setOutlineProvider(viewOutlineProvider);

19.改变drawable颜色

给现有的资源文件改变颜色,就不用重新切图了
慎用 这种方式好像会把所有引用到此文件的颜色都改变 没办法一个地方黑色 一个地方红色 改了就会全改掉

Drawable arrowDrawable = DrawableCompat.wrap(getResources().getDrawable(R.drawable.ic_arrow_black));
DrawableCompat.setTintList(arrowDrawable, getResources().getColorStateList(R.color.gray));
imageView.setImageDrawable(arrowDrawable);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值