Home

Awesome

<br /><br /> jiang111/image <br />

EnglishVersion ->_->:https://github.com/jiang111/awesome-android-tips/blob/master/README-en.md

值得收藏的AS插件 ->_->:https://github.com/jiang111/awesome-androidstudio-plugins <br />

这里收集了大家常用的一些Android代码,持续更新中,内容来自自己的平时积累和网络上看到的文章,部分原文地址在最下方。如有错误欢迎指正,如有侵权,请联系我删除。里面可能会有重复内容,请忽略或者提醒我删除。<br /><br />

Table of Contents

buildTypes {
        release {
            debuggable true   //即使是release模式,但是由于debuggable是true,所以它的BuildConfig.DEBUG值依然是true
        }
        debug {
	    debuggable false //即使是debug模式,但是由于debuggable是false,所以它的BuildConfig.DEBUG值依然是false
        }
    }

所以正常情况下不要配置debuggable字段

createVideoThumbnail(String filePath, int kind)
extractThumbnail(Bitmap source, int width, int height)
//方法1: 
//无title   
requestWindowFeature(Window.FEATURE_NO_TITLE);    
getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN,WindowManager.LayoutParams. FLAG_FULLSCREEN);   
//必须在setContentView()之前调用
setContentView(R.layout.main);  
//方法2:
<activity android:name="." 
    android:theme="@android:style/Theme.NoTitleBar.Fullscreen" //全屏主题
    android:label="@string/app_name" />
public static void printMap(Map mp) {
    for (Map.Entry m : mp.entrySet()) {
            System.out.println(m.getKey() + ":" + m.getValue());
        }
}
public static int randInt(int min, int max) {
    Random rand = new Random();
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}

*备注:大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释:

  1. 数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task,一般情况不推荐;
  2. 数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用;
  3. 数字3:在Receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视);
  4. ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。
  1. 插好数据线,拨号界面 输入 ##2846579## 进入工程模式
  2. projectmenu→3后台设置→4USB端口配置→Balong调试模式,点确定
  3. 不要拔线,退出工程模式,直接重启手机,电脑中显示可移动磁盘(若仍未出现,重复步骤1、2)
  4. 这个是关闭USB调试的情况下电脑中使用手机的可移动磁盘的方法,使用后下拉菜单中usb选项也回来了。
public static Bitmap blurBitmap(Context context, Bitmap src, int radius) {
        Bitmap dest = src.copy(src.getConfig(), true);
        RenderScript rs = RenderScript.create(context);
        Allocation allocation = Allocation.createFromBitmap(rs, src);
        Type t = allocation.getType();
        Allocation blurredAllocation = Allocation.createTyped(rs, t);
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        blurScript.setRadius(radius);
        blurScript.setInput(allocation);
        blurScript.forEach(blurredAllocation);
        blurredAllocation.copyTo(dest);
        allocation.destroy();
        blurredAllocation.destroy();
        blurScript.destroy();
        t.destroy();
        rs.destroy();
        return dest;
    }
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:background="#FF00FF"
    tools:visibility="visible"
    tools:text="这段话只在预览时能看到,运行以后就看不到了" />
android {
    defaultConfig {
    ...
            jackOptions {
                enabled true
            }
        }
   ...
    compileOptions {
        targetCompatibility 1.8
        sourceCompatibility 1.8
    }
}
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
<style name="Theme.YourApp" parent="android:style/Theme.Light">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

这样,控件的宽高默认都是wrap_content样式啦。

<style name="Fill">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
</style>
<style name="Fill.Height" >
    <item name="android:orientation">vertical</item>
</style>

<img src="https://raw.githubusercontent.com/jiang111/awesome-android-tips/master/img/multy_task1.jpg" width = "50%" height="300px" /><img src="https://raw.githubusercontent.com/jiang111/awesome-android-tips/master/img/multy_task2.jpg" width = "50%" height="300px"/>

android {
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            versionNameSuffix '-DEBUG'
        }
        release {
            //...
        }
    }
}
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(linearLayoutManager);
    LinearSnapHelper snapHelper = new LinearSnapHelper();
    snapHelper.attachToRecyclerView(recyclerView);
ArrayMap<K,V> in place of HashMap<K,V> 
ArraySet<K,V> in place of HashSet<K,V> 
SparseArray<V> in place of HashMap<Integer,V> 
SparseBooleanArray in place of HashMap<Integer,Boolean> 
SparseIntArray in place of HashMap<Integer,Integer>  
SparseLongArray in place of HashMap<Integer,Long>  
LongSparseArray<V> in place of HashMap<Long,V>
    return UUID.randomUUID().toString().toUpperCase().replaceAll("-", "");
<item name="android:windowBackground">@null</item>
 Configuration configuration = getResources().getConfiguration();
  configuration.fontScale = (float) 1; 
  //0.85 小, 1 标准大小, 1.15 大,1.3 超大 ,1.45 特大 
  DisplayMetrics metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics); 
  metrics.scaledDensity = configuration.fontScale * metrics.density;
  getBaseContext().getResources().updateConfiguration(configuration, metrics); 
  //(ps:dialog popupwindow 除外,这两种需要在控件中重新设置fontScale)
public class Colors {
    @IntDef({RED, GREEN, YELLOW})
    //声明必要的int常量,使用@IntDef修饰LightColors,参数设置为待枚举的集合
    @Retention(RetentionPolicy.SOURCE)
    //使用@Retention(RetentionPolicy.SOURCE)指定注解仅存在与源码中,不加入到class文件中
    public @interface LightColors{}
    //声明一个注解为LightColors
    public static final int RED = 0;
    public static final int GREEN = 1;
    public static final int YELLOW = 2;
}
//用法
private void setColor(@Colors.LightColors int color) {
        Log.d("MainActivity", "setColor color=" + color);
}
//调用的该方法的时候
setColor(Colors.GREEN);
Path path = new Path();
path.cubicTo(0.2f, 0f, 0.1f, 1f, 0.5f, 1f);
path.lineTo(1f, 1f);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, 500);
animator.setInterpolator(PathInterpolatorCompat.create(path));
animator.start();
public static boolean isNetWorkAvailable(final Context context) {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process pingProcess = runtime.exec("/system/bin/ping -c 1 www.baidu.com");
            int exitCode = pingProcess.waitFor(); //0 代表连通,2代表不通
            return (exitCode == 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
@Override
  public void onBackPressed() {
    moveTaskToBack(false);
  }
try {
	DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	format.setLenient(false);
	//要转换字符串 str_test  自定义的格式为 yyyy-mm-dd,可以改成你需要的格式
	String str_test ="2011-04-24";
	Timestamp ts = new Timestamp(format.parse(str_test).getTime());
	System.out.println(ts.toString());
} catch (ParseException e) {
e.printStackTrace();
}
说明:
API level>=17,允许js 被调用的函数必须以@JavascriptInterface 进行注解,因此不受影响; 对于API level < 17,尽量不要使用addJavascriptInterface,如果一定要用,那么:
1) 使用https 协议加载URL,使用证书校验,防止访问的页面被篡改挂马;
2) 对加载URL 做白名单过滤、完整性校验等防止访问的页面被篡改;
3) 如果加载本地html,应该会HTML 内置在APK 中,以及对HTML 页面进行完整性校验。

//监听Dialog的setOnShowListener方法
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(final DialogInterface dialog) {
      Button negativeButton = ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_NEGATIVE);
      Button positiveButton = ((AlertDialog)dialog).getButton(DialogInterface.BUTTON_POSITIVE);
      negativeButton.invalidate();
      positiveButton.invalidate();
    }
});
dialog.show();

new LinearLayoutManager(this) {
    @Override
    protected int getExtraLayoutSpace(RecyclerView.State state) {
        return size;
    }
};

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            CookieManager.getInstance().setAcceptThirdPartyCookies(WebView, true);
        }
 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                //TODO...
                return false;
            }
        });
配置正常的multiDex库之后,在主模块的gradle文件添加如下代码:
Android{
     ...//其他代码
    dexOptions {
        javaMaxHeapSize "4g"
        preDexLibraries = false
        additionalParameters += '--multi-dex'
        additionalParameters += '--set-max-idx-number=35000'//(35000可根据自己的需求更改)来适配4.0-4.4一些低端机型,因为拆分的dex太大,这些低端机型加载不了dex
        additionalParameters += '--minimal-main-dex'
    }

}

注意:在gradle版本3.1.0之后dex编译采用D8,可能会导致这种分包不成功。将gradle的版本降到3.0.0之后,分包成功。另外也可以采用gradle3.1.0或者以上的版本,然后将项目的gradle配置为android.enableD8=false //暂时关闭 即可

<item name="android:windowIsTranslucent">true</item>

属性,切勿为app设置该属性,而仅针对具体的activity进行设置.公司有位开发为整个app设置了该属性,我们有个签名的横屏页面,其他是强制竖屏页面,有个需求是进入该竖屏页面后某些特殊原因需要自动跳转到签名页面,而跳转到横屏页面后导致整个app的所有页面生命周期全部重新走了一遍,该签名页面无限循环打开.

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (requested.name.startsWith("recyclerview-v7")) {
                details.useVersion "28.0.0"
            }
        }
    }
}

当然,依赖替换规则还允许我们在本地库和远程库之间进行切换.

configurations.all {
    resolutionStrategy.dependencySubstitution {
        if (useLocal) { //如果使用本地仓库,系统将会把org.utils:api依赖替换为本地api的project
            substitute module("org.utils:api") because "we work with the unreleased development version" with project(":api")
        }
    }
}
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {
	    //禁止swipeRefreshLayout拿上下滑动的手势
                swipeRefreshLayout.setEnabled(state == ViewPager.SCROLL_STATE_IDLE);

            }
        });
    public CustomEditText(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.editTextStyle); // 需要传入android.R.attr.editTextStyle 而不是0
    }

摘自如下地址

捐赠

如果您觉得本项目对您有帮助,欢迎请作者一杯咖啡 <br /><br />

Stargazers over time

License

Copyright 2018 NewTab

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.