2015年8月27日 星期四

ContentProvider限制查詢的回傳資料數量

Reference:

http://blog.csdn.net/dalancon/article/details/12618315

說明:

query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

sortOrder
LIMIT <count> OFFSET <skip>
count: 回傳的資料數量
skip: 跳過的資料數量
Ex:
String sortOrder = "name DESC LIMIT 3 OFFSET 2";
按照 name的字母降冪排序,最多只回傳3筆資料,略過首兩筆符合的資料,從第三筆開始回傳

2015年8月19日 星期三

ViewPager

簡介:

透過滑動螢幕,達到切換不同頁面的效果。只要實作 PagerAdapter,就能顯示各個頁面要顯示的內容,每一頁是由一個 Fragment來呈現。
實作 PagerAdapter方面,通常會實作繼承自 PagerAdapter的 FragmentPagerAdapter和 FragmentStatePagerAdapter。Pager的頁面少使用 FragmentPagerAdapter,反之,則使用FragmentStatePagerAdapter。

Code snippet:

@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // add view pager
        mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) v.findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        .........
}

public class SectionsPagerAdapter extends FragmentPagerAdapter{
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0:
fragment = FirstFragment.newInstance();
break;
case 1:
fragment = SecondFragment.newInstance();
break;
case 2:
fragment = ThirdFragment.newInstance();
break;
default:
break;
}
return fragment;
}

@Override
public int getCount() {
return NUMBERS_OF_PAGER;
}

@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
Resources res = getActivity().getResources();
switch (position) {
case 0:
return res.getText(R.string.tab_title_showcase).toString().toUpperCase(l);
case 1:
return res.getText(R.string.tab_title_favorite).toString().toUpperCase(l);
case 2:
return res.getText(R.string.tab_title_recent).toString().toUpperCase(l);
                                ...................
default:
break;
}
return null;
}
}

Critical issue:

https://code.google.com/p/android/issues/detail?id=55068
ViewPager doesn't refresh child fragments when back navigation via backstack

當 FragmentA實作一個 ViewPager,在設定 PagerAdapter的建構子時,要使用 getChildFragmentManager() 取代 getFragmentManager()
官方文件說明如下:

public final FragmentManager getChildFragmentManager ()

Added in API level 17
Return a private FragmentManager for placing and managing Fragments inside of this Fragment.
若使用 getFragmentManager(),當 FragmentA透過 FragmentTransaction跳到 FragmentB,再按 Back鍵回到 Fragment時,ViewPager裡的 Fragment會發生顯示異常
(若要按 Back鍵讓 FragmentB能回到 FragmentA,FragmentTransaction要執行下面程式localFragmentTransaction.addToBackStack(null))
若是由 ViewPager裡的 Fragment利用 FragmentTransaction跳到 FragmentB,要透過 getActivity()取得的 Activity object,來執行 replace(),否則會因為找不到 FragmentA、B容器的 container的resource id而發生 IllegalArgumentException

08-17 16:22:02.328: D/AndroidRuntime(1605): Shutting down VM
08-17 16:22:02.329: E/AndroidRuntime(1605): FATAL EXCEPTION: main
08-17 16:22:02.329: E/AndroidRuntime(1605): Process: org.cyanogenmod.theme.chooser, PID: 1605
08-17 16:22:02.329: E/AndroidRuntime(1605): java.lang.IllegalArgumentException: No view found for id 0x7f0d0003 (org.cyanogenmod.theme.chooser:id/content) for fragment ChooserDetailFragment{25b7e683 #2 id=0x7f0d0003 class org.cyanogenmod.theme.chooser.ChooserDetailFragment}

2015年8月4日 星期二

Eclipse更新 support library後出現了「Jar mismatch! Fix your dependencies」

Reference:

http://www.dotblogs.com.tw/cheng/archive/2014/07/18/r-java-android-jar-mismatch-include-library.aspx

徵狀:

使用 SDK Manager更新 Android Support Library,Eclipse出現下面錯誤訊息
Found 2 versions of android-support-v4.jar in the dependency list,
but not all the versions are identical (check is based on SHA-1 only at this time).
All versions of the libraries must be the same at this time.

原因:

Library專案(Ex: appcompat_v7)和原本專案的「android-support-v4.jar」版本不同,造成的錯誤(Eclipse會自動做sha1來比對是否一致),但不一定是Android的support library,也有可能是其他衝突的jar檔

解決方法:

如果是 support library的話,將 library專案和原本專案的 libs目錄下的「android-support-v4.jar」刪除掉,之後一併在 library專案和原本專案上按右鍵 -> Android Tools -> Add Support Library,將最新的 support library加入,讓兩邊 include的 library一致

2015年8月1日 星期六

Theme and Style

Reference

https://developer.android.com/training/material/theme.html#StatusBar

精通 Android程式介面設計
作者:孫宏明

定義

Theme和 Style都是格式的定義
Theme應用的對象是 Application或 Activity
Style應用的對象是介面元件

Theme

Theme的系列

Theme、Theme.Light、Theme.Holo、Theme.Holo.Light、Theme.Translucent

每個系列可再分為下列五種:
Theme                                              基本型態 (深色系列)
Theme.Dialog                                  對話盒型態
Theme.Panel                                    小窗格型態 (背景透明)
Theme.NoTitleBar                           沒有程式上方的標題列
Theme.NoTitleBar.Fullscreen         讓程式畫面佔滿螢幕

如何讓程式在不同版本的Android使用不同的Theme

在 res下建立 valuse-XX資料夾,並建立 styles.xml資源檔
例如:Android 4.2的 API編號為17,就建立 values-17資料夾


使用 parent屬性指定一個系統內建的 theme,另外可將一些屬性放在 <item>標籤裡,修改 theme的外觀

<resources>

   <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:textSize">25sp</item>
        <item name="android:textColor">#00FF00</item>
    </style>

</resources>

Style

如何建立 Style

建立 Style和建立 Theme的過程類似,因為 Theme就是一種 Style

<style name="MyTextStyle" parent="android:TextAppearance">
        <item name="android:textSize">25sp</item>
        <item name="android:textColor">#FF0000</item>
</style>

<TextView
        style="@style/MyTextStyle"
        android:id="@+id/question_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"      
        android:text="@string/question_label"
        android:textSize="25sp"/>

也可以套用系統預設的 style
<TextView
        style="@android:style/TextAppearance"
        android:id="@+id/question_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"      
        android:text="@string/question_label"
        android:textSize="25sp"/>

在使用系統預設的 style時,可以用?代替@,是說當沒有指定特定style時使用系統預設值
style="?android:textAppearance"


Style的繼承

style提供繼承的功能
當style名稱加上「.」,表示這個 style名稱繼承「.」符號前面一個的 style名稱
例如:
CentHori繼承 MyTextStyle,同時擁有三個屬性
<style name="MyTextStyle" parent="android:TextAppearance">
        <item name="android:textSize">25sp</item>
        <item name="android:textColor">#FF0000</item>
</style>

<style name="MyTextStyle.CentHori">
        <item name="android:layout_gravity">center_horizontal</item>
</style>

這種繼承方式可以系續延伸
<style name="MyTextStyle.CentHori.GreyBack">
        <item name="android:background">#aaaaaa</item>
</style>