學習 Android Developer Blog 上面的兩篇文章——"Implementing Material Design in Your Android app"和"AppCompat v21 — Material Design for Pre-Lollipop Devices!"。自己動手實作,體驗Material Design。
一、準備工作 1、通過SDK Manager下載下傳最新的相容包 2、配置Gradle,引入相容包
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "com.android.support:appcompat-v7:21.0.+"
compile "com.android.support:cardview-v7:21.0.+"
compile "com.android.support:palette-v7:21.0.+"
}
二、Shadow Lollipop通過設定elevation屬性實作陰影效果。一番周折發現,使用相容包無法起效。不過,通過将想要設定陰影的 View 包裹在CardView中,能夠實作相同效果。
三、CardView 效果圖:
布局:
(adjustViewBounds屬性很好用,可以友善的讓ImageView緊緊包裹圖檔而不留白) 四、Dynamic Color 這個很贊。使用Palette類,使得圖檔的配字的顔色(以及背景)跟圖檔的顔色特征相關。 效果圖:
源碼:
public class TestMaterialDesignActivity extends Activity {
private GridView gridView;
private List<Integer> resIds;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_material_design);
gridView = (GridView) findViewById(R.id.gridView);
resIds = new ArrayList<Integer>() {
//static
{
add(R.drawable.test);
add(R.drawable.test4);
add(R.drawable.test5);
add(R.drawable.test7);
}
};
List<String> strs = new ArrayList<String>() {
{
add("cat");
add("cat-dog");
add("cat-dog");
add("cat-dog");
}
};
BaseAdapter adapter = new MyAdapter(this, resIds, strs);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
startActvity(view, resIds.get(position));
}
});
}
class MyAdapter extends BaseAdapter {
private Context context;
private List<Integer> resIds;
private List<String> strs;
MyAdapter(Context context, List<Integer> resIds, List<String> strs) {
this.context = context;
this.resIds = resIds;
this.strs = strs;
}
@Override
public int getCount() {
return resIds.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.grid_item_test_material_design, parent, false);
viewHolder = new ViewHolder();
viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView3);
viewHolder.textView = (TextView) convertView.findViewById(R.id.textView3);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.imageView.setImageResource(resIds.get(position));
viewHolder.textView.setText(strs.get(position));
final ViewHolder finalViewHolder = viewHolder;
Palette.generateAsync(BitmapFactory.decodeResource(context.getResources(), resIds.get(position)),
new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
Palette.Swatch vibrant =
palette.getVibrantSwatch();
if (vibrant != null) {
// If we have a vibrant color
// update the title TextView
finalViewHolder.textView.setBackgroundColor(
vibrant.getRgb());
finalViewHolder.textView
.setTextColor(
vibrant.getTitleTextColor());
}
}
});
return convertView;
}
class ViewHolder {
private ImageView imageView;
private TextView textView;
}
}
}
五、轉場動畫 1、經過嘗試,發現最炫酷的SceneTransitionAnimation在pre Lollipop的裝置上無法實作。 效果沒出來,先看的文檔。
public static ActivityOptions makeSceneTransitionAnimation (Activity activity, View sharedElement, String sharedElementName)
Added in API level 21
Create an ActivityOptions to transition between Activities using cross-Activity scene animations. This method carries the position of one shared element to the started Activity. The position of
sharedElement
will be used as the epicenter for the exit Transition. The position of the shared element in the launched Activity will be the epicenter of its entering Transition.
This requires
FEATURE_ACTIVITY_TRANSITIONS
to be enabled on the calling Activity to cause an exit transition. The same must be in the called Activity to get an entering transition.
Parameters
activity | The Activity whose window contains the shared elements. |
---|---|
sharedElement | The View to transition to the started Activity. |
sharedElementName | The shared element name as used in the target Activity. This must not be null. |
Returns
- Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
See Also
-
setEpicenterCallback(android.transition.Transition.EpicenterCallback)
以為是
FEATURE_ACTIVITY_TRANSITIONS
沒有enabled。設定了之後還是不行。(這裡要注意,requestFeature() must be called before adding content)就看了下源碼。看到源碼就知道肯定無法實作了。
public static ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity,
View sharedElement, String sharedElementName) {
if (Build.VERSION.SDK_INT >= 21) {
return new ActivityOptionsCompat.ActivityOptionsImpl21(
ActivityOptionsCompat21.makeSceneTransitionAnimation(activity,
sharedElement, sharedElementName));
}
return new ActivityOptionsCompat();
}
2、其它轉場動畫 發現 ActivityOption 提供了其他的轉場動畫也不錯。比如下面三個。
public static ActivityOptions makeCustomAnimation (Context context, int enterResId, int exitResId)
Added in API level 16
Create an ActivityOptions specifying a custom animation to run when the activity is displayed.
Parameters
context | Who is defining this. This is the application that the animation resources will be loaded from. |
---|---|
enterResId | A resource ID of the animation resource to use for the incoming activity. Use 0 for no animation. |
exitResId | A resource ID of the animation resource to use for the outgoing activity. Use 0 for no animation. |
Returns
- Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
public static ActivityOptions makeScaleUpAnimation (View source, int startX, int startY, int width, int height)
Added in API level 16
Create an ActivityOptions specifying an animation where the new activity is scaled from a small originating area of the screen to its final full representation.
If the Intent this is being used with has not set its
Intent.setSourceBounds
, those bounds will be filled in for you based on the initial bounds passed in here.
Parameters
source | The View that the new activity is animating from. This defines the coordinate space for startX and startY. |
---|---|
startX | The x starting location of the new activity, relative to source. |
startY | The y starting location of the activity, relative to source. |
width | The initial width of the new activity. |
height | The initial height of the new activity. |
Returns
- Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
public static ActivityOptions makeThumbnailScaleUpAnimation (View source, Bitmap thumbnail, int startX, int startY)
Added in API level 16
Create an ActivityOptions specifying an animation where a thumbnail is scaled from a given position to the new activity window that is being started.
If the Intent this is being used with has not set its
Intent.setSourceBounds
, those bounds will be filled in for you based on the initial thumbnail location and size provided here.
Parameters
source | The View that this thumbnail is animating from. This defines the coordinate space for startX and startY. |
---|---|
thumbnail | The bitmap that will be shown as the initial thumbnail of the animation. |
startX | The x starting location of the bitmap, relative to source. |
startY | The y starting location of the bitmap, relative to source. |
Returns
- Returns a new ActivityOptions object that you can use to supply these options as the options Bundle when starting an activity.
六、Theme.AppCompat.Light 使用相容包裡的樣式擷取Android L 控件的樣式,風格很統一,控制顔色也非常友善。 相容包支援以下控件:
- Everything provided by AppCompat’s toolbar (action modes, etc)
-
EditText
-
Spinner
-
CheckBox
-
RadioButton
-
(use the newSwitch
)android.support.v7.widget.SwitchCompat
-
CheckedTextView
效果圖:
注意,為了使樣式生效,Activity 需繼承相容包裡的ActionBarActivity。
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">@color/my_awesome_color
</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">@color/my_awesome_darker_color
</item>
<!-- colorAccent is used as the default value for colorControlActivated,
which is used to tint widgets -->
<item name="colorAccent">@color/accent</item>
<item name="colorControlHighlight">@color/my_awesome_color</item>
<item name="colorControlNormal">@color/my_awesome_color</item>
<item name="colorControlActivated">@color/my_awesome_color</item>
<item name="colorSwitchThumbNormal">@color/my_awesome_color</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight, and colorSwitchThumbNormal. -->
</style>
<color name="my_awesome_color">#009688</color>
<color name="my_awesome_darker_color">#004D40</color>
<color name="accent">#CDDC39</color>
</resources>