Android 雜技

手勢操做onScroll沒有執行(以及onFling問題)

現象1

將某一手勢操做交給GestureDetector時,GestureDetector重寫了幾個方法,可是onScroll沒有執行,其餘的onDOwn,OnLongPress都有執行。html

解決:onDOwn方法的返回值返回truejava

現象2

雖然此時onScroll(滑動)方法調用了,可是打印結果表示:該方法會調用屢次,有時並非我所須要的,而onFling表示滑動,當手離開時調用,可是打印的結果顯示並無調用;android

解決:在以前的基礎上再將onScroll返回false便可!ios

原文連接:https://blog.csdn.net/flycatdeng/article/details/18267133web

ImageSpan

// 第一種
Drawable drawable = getResources().getDrawable(R.drawable.ic_coin);
drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
// 第一種
ImageSpan imageSpan = new ImageSpan(mContext, R.drawable.ic_coin);

stringBuilder.setSpan(imageSpan, size-1, size, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

FragmentPagerAdapter與FragmentStatePagerAdapter區別

https://www.cnblogs.com/lianghui66/p/3607091.htmlapache

判斷 RecyclerView 到達底部的方法

第1種

/**
 * 判斷是否滑動到底部
 */
public static boolean isSlideToBottom(RecyclerView recyclerView) {
    if (recyclerView == null) return false;
    return recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
            >= recyclerView.computeVerticalScrollRange();
}

/**
 * 判斷是否滑動到頂部
 */
public static boolean isSlideToTop(RecyclerView recyclerView) {

    if (recyclerView == null) return false;
    return recyclerView.computeVerticalScrollOffset() == 0;
}

第2種

/**
 * 判斷是否滑動到底部
 */
public static boolean isSlideToBottom(RecyclerView recyclerView) {
   return !recyclerView.canScrollVertically(1); //表示是否能向上滾動,false 表示已經滾動到底部 
}

/**
 * 判斷是否滑動到頂部
 */
public static boolean isSlideToTop(RecyclerView recyclerView) {
    return !recyclerView.canScrollVertically(-1); // 表示是否能向下滾動,false 表示已經滾動到頂部
}

第3種

RecyclerView rvMessage = findViewById(R.id.rv_message);

    GridLayoutManager layoutManager = new GridLayoutManager(this, 1, RecyclerView.VERTICAL, false);
    rvMessage.setLayoutManager(layoutManager);
    MessageAdapter messageAdapter = new MessageAdapter();
    rvMessage.setAdapter(messageAdapter);

    rvMessage.addOnScrollListener(new RecyclerView.OnScrollListener() {

        private int lastVisible = 0;

        [@Override](https://my.oschina.net/u/1162528)
        public void onScrollStateChanged([@NonNull](https://my.oschina.net/u/2981441) RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == RecyclerView.SCROLL_STATE_IDLE &&
                    lastVisible + 1 == messageAdapter.getItemCount()) {

                // 已滑動到底部
            }
        }

        [@Override](https://my.oschina.net/u/1162528)
        public void onScrolled([@NonNull](https://my.oschina.net/u/2981441) RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            lastVisible = layoutManager.findLastCompletelyVisibleItemPosition();
        }
    });

參考api

http://quanzhan.applemei.com/webStack/TVRrNE9RPT0=緩存

將十六進制 顏色代碼 轉換爲int類型數值

Color.parseColor("#FF00FF")網絡

getColor在6.0中過期

MainActivity.this.getResources().getColor(R.color.colorTest)

用如下替換app

ContextCompat.getColor(context, R.color.my_color)
//源碼 
public static final int getColor(Context context, int id)
{
final int version = Build.VERSION.SDK_INT;
if (version >= 23) {
	return ContextCompatApi23.getColor(context, id);       
} else {
	return context.getResources().getColor(id);
	}
}

SparseArray

SparseArray是android裏爲<Interger,Object>這樣的Hashmap而專門寫的class,目的是提升效率,其核心是折半查找函數(binarySearch)

Listview的Adapter的轉換

若是ListView沒有headerView或者footerView的時候,與listView相關聯的Adapter就是傳進來的參數Adapter,若是有,就將原來的Adapter包裝成HeaderViewListAdapter,HeaderViewListAdapter有個方法getWrappedAdapter,該方法能返回被包裝的HeaderViewListAdapter的ListAdapter。

HeaderViewListAdapter headerViewListAdapter = (HeaderViewListAdapter) listView.getAdapter(); 
ContactAdapter contactAdapter = (ContactAdapter) headerViewListAdapter.getWrappedAdapter();

使用View作虛線分割線

drawable/line_dash.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="line">
    <stroke android:color="@color/colorBlack"
            android:dashGap="2dp"
            android:dashWidth="5dp"
            android:width="1dp" />
    <size android:width="1dp" />
</shape>

佈局文件中:(須要設置 layerType爲software)

<View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@drawable/line_dash"
        android:layerType="software"
        />

Android api23 刪除HttpClient 相關類

在Module的gradle.build文件添加依賴,和 packagingOptions,和 useLibrary 'org.apache.http.legacy'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.egrid.webdemo"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

     packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    //會加載Andrdoid自帶的jar包 org.apache.http.legacy.jar
     useLibrary 'org.apache.http.legacy'
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    //下面這些不會起做用
    compile 'org.apache.httpcomponents:httpclient:4.3.6'
    compile 'org.apache.httpcomponents:httpcore:4.3.2'
}

在xml中使用系統的actionBarSize

  1. 在attrs.xml文件中定義
<resources>
    <declare-styleable name="app">
        <attr name="toolbarHeight" format="dimension" />
    </declare-styleable>
</resources>
  1. 在styles.xml中自定義toolbarHeight爲actionBarSize
<style name="BaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="colorButtonNormal">@color/blueLight</item>
        <item name="colorControlHighlight">@color/background</item>
        <item name="toolbarHeight">?android:attr/actionBarSize</item>
    </style>
  1. 在佈局xml中使用
<androidx.appcompat.widget.Toolbar
	 android:id="@+id/toolbar"
	 android:layout_width="match_parent"
	 android:layout_height="?attr/toolbarHeight"
	 app:contentInsetStart="0dp"
	 app:layout_collapseMode="pin" />

Splash 的最佳實踐

此方法是給主界面設置閃屏頁主題,在主界面中再用代碼換回主界面主題,實現無閃屏Activity達到閃屏頁的效果。

  1. 閃屏主題
<resources>
  <!-- 主界面主題 -->
  <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
  </style>
   <!-- 閃屏主題 -->
  <style name="AppTheme.Launcher">
    <item name="android:windowBackground">@drawable/launch_screen</item>
  </style>
<resources>
  1. 閃屏界面背景drawable/launch_screen.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:opacity="opaque">
    <item android:drawable="@color/white" />
     <bitmap
            android:gravity="center"
            android:src="@drawable/img_splash" />
</layer-list>
  1. 主界面設置主題
<activity
 android:name=".ui.activity.MainActivity"
 android:theme="@style/AppTheme.Launcher">
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
  1. 主界面super.onCreate() 以前調用 onCall() 方法設置迴應用主題
public class MainActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceStated) {
    setTheme(R.style.AppTheme);
    super.onCreate(savedInstanceStated);
    // ...
  }
}

注:如有閃屏Activity能夠直接使用主題設置閃屏背景,無需在佈局設置背景,因此沒有背景顯示時的切換問題

連接:https://blog.csdn.net/zujack/article/details/69499350

TextView 設置和取消刪除線的兩種方法

設置刪除線

  1. (推薦)經過按位或運算符|,將 TextView 本來的 Flags 屬性和刪除線一塊設置。setPaintFlags內會對 TextView 進行重繪。
tv.setPaintFlags(tv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
  1. 獲取畫筆後設置屬性,重繪 TextView 。此方式有個問題,會把 TextView 本來的 Flags 屬性替代,例如抗鋸齒等。仔細查看,你會發現經過這種方式,文字有了鋸齒。
tv.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
tv.invalidate();

取消刪除線

  1. (推薦)先對 Paint.STRIKE_THRU_TEXT_FLAG 屬性取反,再用按位與運算符&,除去了刪除線屬性並保留了 TextView 本來的 Flags 屬性。setPaintFlags內會對 TextView 進行重繪。
tv.setPaintFlags(tv.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
  1. 獲取畫筆後,清空 Flags 屬性,再重繪 TextView 。此方式有個問題,會把 TextView 本來的全部 Flags 屬性清空,例如抗鋸齒等。仔細查看,你會發現經過這種方式,文字有了鋸齒;
tv.getPaint().setFlags(0);
tv.invalidate();

參考:https://www.jb51.net/article/136661.htm

RecyclerView滾動到指定位置並置頂

// 自定義類
 public class TopSmoothScroller extends LinearSmoothScroller {

    public TopSmoothScroller(Context context) {
        super(context);
    }

    @Override
    protected int getHorizontalSnapPreference() {
        return SNAP_TO_START;//具體見源碼註釋
    }

    @Override
    protected int getVerticalSnapPreference() {
        return SNAP_TO_START;//具體見源碼註釋
    }
}

// 使用
 LinearSmoothScroller scroller = new TopSmoothScroller(CourseActivity.this);
 scroller.setTargetPosition(position);
 linearLayoutManager.startSmoothScroll(scroller);

用shape畫的虛線在真機上沒法顯示

在佈局View添加屬性 android:layerType="software"

安裝debug包時手機(OPPO VIVO)顯示INSTALL_FAILED_TEST_ONLY沒法安裝

Android Studio 3.0之後會在debug apk的manifest文件中加android:testOnly=」true」 屬性,此屬性沒法在非開發者模式的手機上安裝,VIVO OPPO即便在開發者模式也不能安裝。

解決: 在gradle.properties文件中添加android.injected.testOnly=false

沉浸式模式

Android關於沉浸式狀態欄總結

http://www.javashuo.com/article/p-vkodzher-bo.html

Android狀態欄微技巧,帶你真正理解沉浸式模式

https://blog.csdn.net/guolin_blog/article/details/51763825

Android 沉浸式狀態欄必知必會

https://juejin.im/entry/58cb481744d9040069f57266

劉海屏適配cutout

劉海屏適配 與WindowInsets,DisplayCutout使用

https://blog.csdn.net/yi_master/article/details/80309757

Android Studio配置文件路徑修改

.AndroidStudio文件夾修改

修改文件C:\Program Files\Android\Android Studio\bin\idea.properties中的

idea.config.path=D:/Android/.AndroidStudio/config
idea.system.path=D:/Android/.AndroidStudio/system

.gradle文件夾的修改

設置Android Studio中的 Settings->Build,Execution,Deployment->Gradle 中的Service directory path爲D:/Android/.gradle

.android文件夾的修改 添加一個系統的環境變量ANDROID_SDK_HOME爲D:/Android/avd

https://www.jianshu.com/p/7a58c5f154c5

Android 經常使用尺寸

密度 ldpi mdpi hdpi xhdpi xxhdpi xxxhdpi
比例 0.75 1 1.5 2 3 4
密度數 120dpi 160dpi 240dpi 320dpi 480dpi 640dpi
表明分辨率 240*320 320*480 480*800 720*1280 1080*1920 1440*2560
Launcher And Home 36*36 48*48 72*72 96*96 144*144 192*192
Action Bar And Tab 24*24 32*32 48*48 64*64 96*96 128*128
Notification 18*18 24*24 36*36 48*48 72*72 96*96
Background 320*426 320*470 480*640 720*1280 1080*1920 1440*2560

Android Studio一直 Fetching Documentation...

修改「C:\Users\Administrator\.AndroidStudio2.3\config\options\jdk.table.xml」文件

<javadocPath>
  <root type="composite">
	<root type="simple" url="file://D:/Android/sdk/platforms/reference/" />
  </root>
</javadocPath>

Android 顏色透明度換算

100% — FF
95% — F2
90% — E6
85% — D9
80% — CC
75% — BF
70% — B3
65% — A6
60% — 99
55% — 8C
50% — 80
45% — 73
40% — 66
35% — 59
30% — 4D
25% — 40
20% — 33
15% — 26
10% — 1A
5% — 0D
0% — 00

TabLayout添加 tab分割線

LinearLayout linearLayout = (LinearLayout) tabContent.getChildAt(0);
    linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
    linearLayout.setDividerPadding(CommonUtils.dp2px(this, 8));
    linearLayout.setDividerDrawable(ContextCompat.getDrawable(this,
            R.drawable.layout_divider_vertical));

layout_divider_vertical.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android">
	<solid android:color="@color/grayDark"/>
	<size android:width="1dp"/>
</shape>

將十六進制 顏色代碼 轉換爲int類型數值

Color.parseColor("#FF00FF")

getColor在6.0中過期

MainActivity.this.getResources().getColor(R.color.colorTest) 用一下替換

ContextCompat.getColor(context, R.color.my_color)
//源碼 public static final int getColor(Context context, int id) { 
final int version = Build.VERSION.SDK_INT; 
    if (version >= 23) { 
        return ContextCompatApi23.getColor(context, id);
    } else {
        return context.getResources().getColor(id);  
    }
}

SparseArray

SparseArray是android裏爲<Interger,Object>這樣的Hashmap而專門寫的class,目的是提升效率,其核心是折半查找函數(binarySearch)

Listview的Adapter的轉換

若是ListView沒有headerView或者footerView的時候,與listView相關聯的Adapter就是傳進來的參數Adapter,若是有,就將原來的Adapter包裝成HeaderViewListAdapter,HeaderViewListAdapter有個方法getWrappedAdapter,該方法能返回被包裝的HeaderViewListAdapter的ListAdapter。

HeaderViewListAdapter headerViewListAdapter = (HeaderViewListAdapter) listView.getAdapter(); ContactAdapter contactAdapter = (ContactAdapter) headerViewListAdapter.getWrappedAdapter();

使用View作虛線分割線

drawable/line_dash.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="line"

    >
    <stroke android:color="@color/colorBlack"
            android:dashGap="2dp"
            android:dashWidth="5dp"
            android:width="1dp"
            />
    <size android:width="1dp" />
</shape>

佈局文件中:(須要設置 layerType爲software)

<View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@drawable/line_dash"
        android:layerType="software"
        />

Android api23 刪除HttpClient 相關類

在Module的gradle.build文件添加依賴,和 packagingOptions,和 useLibrary 'org.apache.http.legacy'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

defaultConfig {
    applicationId "com.egrid.webdemo"
    minSdkVersion 16
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    //會加載Andrdoid自帶的jar包 org.apache.http.legacy.jar
     useLibrary 'org.apache.http.legacy'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    //下面這些不會起做用
    compile 'org.apache.httpcomponents:httpclient:4.3.6'
    compile 'org.apache.httpcomponents:httpcore:4.3.2'
}

橫豎屏切換

android:configChanges="orientation|keyboardHidden|screenSize"

移動Android Studio默認的AVD目錄(.android)

Move .android folder to E:\Android\
Create environment variable called ANDROID_SDK_HOME and set its value to E:\Android

Setting environment variable in Windows XP:

	Right-click on My Computer and choose "Properties")
	Click the "Advanced" tab
	Click the button "Environment Variables".
	Add New variable

https://stackoverflow.com/questions/3109473/moving-default-avd-configuration-folder-android

獲取當前Activity的根視圖

View rootView = getWindow().getDecorView().findViewById(android.R.id.content); 
或者:
View rootView = findViewById(android.R.id.content); 
或者:
View rootView = findViewById(android.R.id.content).getRootView(); 
關於android.R.id.content,開發者文檔中並無給予說明,但通過測試它應該是用來獲取setContentView()中設置的View。

http://www.cnblogs.com/littlepanpc/p/4506294.html

Activity啓動模式

https://inthecheesefactory.com/blog/understand-android-activity-launchmode/en

語言的複數形式

getQuantityString() 

<resources>
    <plurals
        name="plural_name">
        <item
            quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
            >text_string</item>
    </plurals>
</resources>

https://developer.android.com/guide/topics/resources/string-resource.html#Plurals
http://blog.csdn.net/a78270528/article/details/46791533

應用運行檢測

/**
 * 檢測應用是否在後臺運行
 * [@param](https://my.oschina.net/u/2303379) context context
 * [@return](https://my.oschina.net/u/556800) true 後臺運行
 */
public static boolean isBackgroundRunning(final Context context) {
	ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
	List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(am.getRunningAppProcesses().size());
	for (ActivityManager.RunningTaskInfo runningTaskInfo : tasks) {
		if (runningTaskInfo.topActivity.getPackageName().equals(context.getPackageName())) {
			Log.d(TAG, "packageName:" + runningTaskInfo.topActivity.getPackageName());
			Log.d(TAG, "className:" + runningTaskInfo.topActivity.getClassName());
			return true;
		}
	}
	return false;
}

/**
 * 檢測應用是否在後臺運行
 * [@param](https://my.oschina.net/u/2303379) context context
 * [@return](https://my.oschina.net/u/556800) true 前臺運行
 */
public static boolean isFrontRunning(Context context) {
	ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
	List<ActivityManager.RunningAppProcessInfo> runningProcesses = am.getRunningAppProcesses();
	for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
		if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
			for (String activeProcess : processInfo.pkgList) {
				if (activeProcess.equals(context.getPackageName())) {
					Log.d(TAG, "packageName:" + activeProcess);
					Log.d(TAG, "className:" + processInfo.processName);
					return true;
				}
			}
		}
	}
	return false;
}

app過大錯誤

問題:

Error:Execution failed for task ':app:transformClassesWithDexForDevDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536

修改文件:

build.gradle 文件

android {
	compileSdkVersion 21
	buildToolsVersion "21.1.0"

	defaultConfig {
		...
		minSdkVersion 14
		targetSdkVersion 21
		...

		// Enabling multidex support.
		multiDexEnabled true
	}
	...
}

dependencies {
  compile 'com.android.support:multidex:1.0.0'
}

Application類

<application
    ...
    android:name="com.test.TestApplication">
    ...
</application>

public class TestApplication extends Application {

	protected void attachBaseContext(Context base) {
		super.attachBaseContext(base);
		MultiDex.install(this);
	}
}

詳情:

https://developer.android.com/studio/build/multidex.html
http://stackoverflow.com/questions/26609734/how-to-enable-multidexing-with-the-new-android-multidex-support-library/38473900#38473900

Android 應用圖標

m		1		48*48px
h		1.5		72*72px
xh		2		96*96px
xxh		3		144*144px
xxxh	4		192*192px

1.CTRL+A  再選擇編輯中的「描邊」就行。(選擇本身喜歡的顏色、設置本身須要的寬度) 
2.新建圖層--矩形選框--反選--填充--快速蒙板--濾鏡(多用幾個)--退出蒙板--圖層效果
3.矩形選區--快速蒙板--濾鏡(各類濾鏡有不一樣的效果,能夠同時用多個濾鏡)--退出蒙板--反選--刪除--描邊

ios和安卓切圖換算比例

1dp(Android)=1pt(iOS)

以48dp@160dpi計算的話

mdpi 48px (160dpi, 1x) 基礎尺寸

hdpi 72px (240dpi, 1.5x)

xhdpi 96px (320dpi, 2x) 同iOS @2x

xxdpi 144px (480dpi, 3x) 同iOS @3x

xxxdpi 192px (640dpi, 4x)

連接:http://www.zhihu.com/question/27038815/answer/34992846

android網絡請求與頁面切換

在android開發中會遇到使用fragment切換頁面,而且切換的頁面都會有網絡請求,網絡請求成功後會更新相應的fragment頁面。若是使用異步網絡請求組件android-async-http,會出現這樣的狀況,當你快速的切換fragment時,每一個fragment都會發出新的請求。例如:fragmentA發了網絡請求,又切換到了fragmentB,fragmentB又發了網絡請求,而後快速的切換兩個fragment,切換屢次後可能會出現,fragmentA發出的請求返回成功而且使用handler發出消息請求改變fragmentA中的UI時,這時當前的頁面正是fragmentB。此時會報空指針錯誤。

解決此類問題,能夠經過第一次加載時緩存,再次切換到此頁面時,只有下拉才能請求新數據。另外一種方法是,設置一個public static volatile int flag;變量,若是flag爲1時則表示當前頁面在fragmentA中,當flag爲2時表示當前頁面在fragmentB中,只當handler收到消息而且flag=1時才能更新fragmentA中的數據。第二種方法實現起來比較繁鎖,推薦使用第一種方法。其中一、二、3這些最好存放在一個枚舉類型中。

[轉]http://blog.csdn.net/wode_dream/article/details/41480271

訪問UI線程

1)Activity.runOnUiThread(Runnable)

2)View.post(Runnable)

public void onClick(View v) {
  new Thread(new Runnable() {
	public void run() {
	  final Bitmap b = loadImageFromNetwork();
	  mImageView.post(new Runnable() {
		public void run() {
		  mImageView.setImageBitmap(b);
		}
	  });
	}
  }).start();
}

3)View.postDelayed(Runnable, long)

4)Handler

final Handler myHandler = new Handler();

(new Thread(new Runnable() {

	@Override
	public void run() {
	   final Bitmap b = loadImageFromNetwork();
	  myHandler.post(new Runnable() {                           

		@Override
		public void run() {
		   mImageView.setImageBitmap(b);
		  }
		});
	  }
	})).start();                
}

ListView嵌套 父ListView高度設置

/**
 * 調整ListView嵌套後,根據子ListView的高度重設父ListView的高度
 * @param listView
 */
public static void setListViewHeightBasedOnChildren(ListView listView) {
	ListAdapter listAdapter = listView.getAdapter();
	if (listAdapter == null) {
		return;
	}

	int totalHeight = 0;
	for (int i = 0; i < listAdapter.getCount(); i++) {
		View listItem = listAdapter.getView(i, null, listView);
		listItem.measure(0, 0);
		totalHeight += listItem.getMeasuredHeight();
	}

	ViewGroup.LayoutParams params = listView.getLayoutParams();
	params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
	listView.setLayoutParams(params);
}

代碼建立控件

ImageView imageView = new ImageView(getActivity());
    //父控件是LinearLayout
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
           ViewGroup.LayoutParams.WRAP_CONTENT,
           ViewGroup.LayoutParams.WRAP_CONTENT);
    //至關於android:layout_gravity屬性  
    params.gravity = Gravity.CENTER_VERTICAL;
    imageView.setLayoutParams(params);
    imageView.setScaleType(ImageView.ScaleType.FIT_XY);

    Button button = new Button(getActivity());
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
    button.setLayoutParams(params);
    //至關於android:gravity屬性 
    button.setGravity(Gravity.CENTER_VERTICAL);

    linearLayout.addView(imageView);
    linearLayout.addView(button);

文本拼接

%1表示第一個位置,$d表示數字,$s表示文本

<string name="sale_comment_text1">【%1$d】</string>
<string name="sale_comment_text2">%1$s評價%2$s</string>

getString(R.string.sale_comment_text1,pojo.getCommentType())
getString(R.string.sale_comment_text2,pojo.getCustomerName(),pojo.getSalesName())

拼接文本爲:【2】,張三評價李四

textAppearance

textAppearanceInverse/

textAppearanceLarge/

textAppearanceLargeInverse/

textAppearanceMedium/

textAppearanceSmallInverse/

textAppearanceMediumInverse/

textAppearanceSmall/

代碼中加下劃線 textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG ); //下劃線 textView.getPaint().setAntiAlias(true);//抗鋸齒

轉:http://www.cnblogs.com/-cyb/archive/2011/08/02/Android_textAppearance.html

gradle dependencies 設置 版本號

ext{
    compileLibVersion = '23.3.0'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile "com.android.support:appcompat-v7:[$compileLibVersion]"
}

隱藏/移除ActionBar

//隱藏掉整個ActionBar,包括下面的Tabs  
getSupportActionBar().hide();
//或
requestWindowFeature(Window.FEATURE_NO_TITLE);  

//會保留tab標籤
//高版本能夠換成 ActionBar actionBar = getActionBar();  
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);  
actionBar.setDisplayShowHomeEnabled(false);

判斷SDK版本

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window window = getWindow();
            // Translucent status bar
            window.setFlags(
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }

Android M運行權限問題

一行代碼解決Android M新的運行時權限問題: http://www.jianshu.com/p/d3a998ec04ad

Android Build.VERSION.SDK_INT兼容介紹

http://aijiawang-126-com.iteye.com/blog/1481572

相關文章
相關標籤/搜索