Fragment
Fragment(碎片)就是小型的Activity,它是在Android3.0 時出現的。
- 可以把fragment 想象成activity的一個模塊化區域
- 有它自己的生命週期,接收屬於它自己的輸入事件,並且可以在activity運行期間添加和刪除
Fargment入門
- 爲Fragment 定義一個佈局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="我是Fragment1裏面的內容"
android:textColor="#ff0000" />
</LinearLayout>
- 定義類繼承Fragment
- 重寫類中的onCreateView 方法,返回一個View 對象作爲當前Fragment 的根佈局。如果fragment 不提供UI,可以返回null
//定義Fragment 理解爲 是Activity的一部分
public class Fragment1 extends Fragment {
//當系統第一次畫ui的時候調用 通過這個方法方法可以讓Fragment顯示自己的佈局內容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//通過打氣筒把一個佈局轉換成一個View對象
View view = inflater.inflate(R.layout.fragment1, null);
return view;
}
}
- 展示:一是使用佈局配置,二是代碼動態加載
配置
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.itheima.fragmendemo.Fragment1"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
動態加載
public class MainActivity extends Activity {
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]獲取手機的分辨率
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int width = wm.getDefaultDisplay().getWidth();
int height = wm.getDefaultDisplay().getHeight();
//[2]判斷橫豎屏
//[3]獲取Fragment的管理者 通過上下文直接獲取
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction(); //開啓事物
if(height > width){
//說明是豎屏 加載一個Fragment android.R.id.content //代表當前手機的窗體
beginTransaction.replace(android.R.id.content, new Fragment1());
}else {
//說明是橫屏 加載一個Fragment
beginTransaction.replace(android.R.id.content, new Fragment2());
}
//[4]最後一步 記得comment
beginTransaction.commit();
}
}
示例 使用Fragment模仿微信界面佈局
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// [1]找到按鈕
Button btn_wx = (Button) findViewById(R.id.btn_wx);
Button btn_contact = (Button) findViewById(R.id.btn_contact);
Button btn_disconver = (Button) findViewById(R.id.btn_disconver);
Button btn_me = (Button) findViewById(R.id.btn_me);
// [2]設置點擊事件
btn_wx.setOnClickListener(this);
btn_disconver.setOnClickListener(this);
btn_me.setOnClickListener(this);
btn_contact.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//[4]獲取Fragment的管理者
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 具體判斷點擊的是哪個按鈕
switch (v.getId()) {
case R.id.btn_wx: // 點擊的是微信
beginTransaction.replace(R.id.ll_layout, new WxFragment());
break;
case R.id.btn_contact: // 點擊的是聯繫人
beginTransaction.replace(R.id.ll_layout, new ContactFragment());
break;
case R.id.btn_disconver: // 點擊的發現
beginTransaction.replace(R.id.ll_layout, new DiscoverFragment());
break;
case R.id.btn_me: // 點擊的是我
beginTransaction.replace(R.id.ll_layout, new MeFragment());
break;
}
//記得comment
beginTransaction.commit();
}
}
Fragment 的生命週期
onAttach:綁定到activity
onCreate:創建fragment
onCreateView: 創建fragment 的佈局
onActivityCreated: activity 創建完成後
onStart: 可見, 不可交互
onResume: 可見, 可交互
onPause: 部分可見, 不可交互
onStop:不可見
onDestroyView: 銷燬fragment 的view 對象
onDestroy: fragment 銷燬了
onDetach: 從activity 解綁了
- Fragment 的向下兼容
Fragment 是在Android 3.0 才推出的
- 把所有Fragment 和FragmentManager 改成support-v4 包下的類
- 把Activity 的繼承改爲FragmentActivity(support-v4 包下的)
Fragment 之間的通信案例
Fragment有一個公共的橋樑 Activity
Fragment1
//定義Fragment 理解爲 是Activity的一部分 public class Fragment1 extends Fragment { //當系統第一次畫ui的時候調用 通過這個方法方法可以讓Fragment顯示自己的佈局內容 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //通過打氣筒把一個佈局轉換成一個View對象 View view = inflater.inflate(R.layout.fragment1, null); //[1]找到按鈕 設置點擊事件 view.findViewById(R.id.btn_update).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //[2]修改fragment2裏面的內容 通過fragment的公共橋樑 --->activity Fragment2 fragment2 = (Fragment2) getActivity().getFragmentManager().findFragmentByTag("f2"); fragment2.updateText("哈哈哈呵呵"); } }); return view; } }
Fragment2
public class Fragment2 extends Fragment {
private TextView tv_content;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, null);
//[1]找到tv
tv_content = (TextView) view.findViewById(R.id.tv_content);
return view;
}
//修改textview的內容
public void updateText(String content){
tv_content.setText(content);
}
}
AutoCompleteTextView
示例
<AutoCompleteTextView
android:id="@+id/actv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
/>
代碼
public class MainActivity extends Activity {
//模擬actv這個控件要顯示的數據
private String[] COUNTRIES = new String[] {
"laofang", "laoli", "laozhang", "laobi", "laowang","aa","abb","ccc"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]找到控件
AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.actv);
//[2]actv這個控件顯示數據的原理和listview一樣 需要一個數據適配器
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, COUNTRIES);
//[3]顯示數據
actv.setAdapter(adapter);
}
}
動畫
Android 3.0 以前,Android 支持兩種動畫模式,tween animation,frame animation
在android3.0 中又引入了一個新的動畫系統:property animation
幀動畫Frame Animation
Frame Animation(幀動畫):創建一個Drawable 序列,這些Drawable 可以按照指定的時間間隔一個一個的顯示,也就是順序播放事先做好的圖像。
- 將準備好的圖片文件放到res/drawable-hdpi 目錄中。
- 在項目的res 目錄下創建文件夾drawable,然後在文件夾下面定義動畫XML 文件,文件名稱可以自定義,例如frame_anim.xml。
- 打開創建好的xml 文件,在裏面添加根節點,
- 可以在此根節點中設置屬性”android:oneshot”來控制動畫只播放一次,否則系統將默認持續播放。在根節點 下爲幀動畫的每幅圖片添加一個 節點, 節點的”android:drawable”屬性是圖片的資源id,”android:duration”屬性指定圖片展示的時間(一般每秒展示5-8 張圖片就可以感受到動畫的效果)。
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true" >
<item
android:drawable="@drawable/a1"
android:duration="200">
</item>
<item
android:drawable="@drawable/a2"
android:duration="200">
</item>
</animation-list>
- 在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次。
- 最後一點是SDK 中提到的, 不要在onCreate 中調用start , 因爲AnimationDrawable 還沒有完全跟Window 相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。
代碼
public class MainActivity extends Activity {
private ImageView iv;
private AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.drawable.frame_anim);
animationDrawable = (AnimationDrawable) iv.getDrawable();
}
public void startAnimation(View view) {// 點擊按鈕調用此方法
if (animationDrawable.isRunning())
animationDrawable.stop();
animationDrawable.start();
}
}
補間(漸變)動畫 TweenAnimation
View Animation(Tween Animation):補間動畫,給出兩個關鍵幀,通過一些算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。
漸變包括:包括平移、縮放、旋轉、改變透明度
特性:
動畫效果不會改變控件真實的座標
只能應用於View 對象,而且只支持一部分屬性,如支持縮放旋轉而不支持背景顏色的改變。
- 使用代碼實現補間動畫
常用的方法
Animation:
setDuration 設置動畫的執行時間
setRepeatCount 設置動畫的重複次數
setRepeatMode 指定重複的模式(如:反轉)
setFillAfter 指示動畫指定完畢之後控件的狀態是否停留在動畫停止的時候
setAnimationListener 設置動畫的事件監聽器
ImageView:
startAnimation(Animation a) 讓ImageView 執行某動畫
示例代碼
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 這個控件用來執行動畫
iv = (ImageView) findViewById(R.id.iv);
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "你點不到我", 1).show();
}
});
}
// 點擊按鈕 實現透明效果
public void click1(View v) {
//創建透明動畫 1.0意味着完全不透明 0.0意外者完全透明
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);
aa.setDuration(2000); //設置動畫執行的時間
aa.setRepeatCount(1); //設置動畫重複的次數
aa.setRepeatMode(Animation.REVERSE); //設置重複的模式
//開始執行動畫
iv.startAnimation(aa);
}
// 點擊按鈕 實現旋轉效果
public void click2(View v) {
//fromDegrees 開始角度 toDegrees 結束的角度
// RotateAnimation ra = new RotateAnimation(0, 360);
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(2000); //設置動畫執行的時間
ra.setRepeatCount(1); //設置動畫重複的次數
ra.setRepeatMode(Animation.REVERSE); //設置重複的模式
//開始執行動畫
iv.startAnimation(ra);
}
// 點擊按鈕 實現縮放效果
public void click3(View v) {
ScaleAnimation sa = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000); //設置動畫執行的時間
sa.setRepeatCount(1); //設置動畫重複的次數
sa.setRepeatMode(Animation.REVERSE); //設置重複的模式
//開始執行動畫
iv.startAnimation(sa);
}
// 點擊按鈕 實現平移效果
public void click4(View v) {
TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.2f);
ta.setDuration(2000); //設置動畫執行的時間
ta.setFillAfter(true);//當動畫結束後 停留在結束的位置上
//開始執行動畫
iv.startAnimation(ta);
}
//點擊按鈕 讓動畫一起執行
public void click5(View v) {
//創建動畫的合集
AnimationSet set = new AnimationSet(true);
AlphaAnimation aa = new AlphaAnimation(1.0f, 0.0f);
aa.setDuration(2000); //設置動畫執行的時間
aa.setRepeatCount(1); //設置動畫重複的次數
aa.setRepeatMode(Animation.REVERSE); //設置重複的模式
RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(2000); //設置動畫執行的時間
ra.setRepeatCount(1); //設置動畫重複的次數
ra.setRepeatMode(Animation.REVERSE); //設置重複的模式
ScaleAnimation sa = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000); //設置動畫執行的時間
sa.setRepeatCount(1); //設置動畫重複的次數
sa.setRepeatMode(Animation.REVERSE); //設置重複的模式
//添加動畫
set.addAnimation(aa);
set.addAnimation(ra);
set.addAnimation(sa);
//執行動畫
iv.startAnimation(set);
}
}
- 使用XML實現補間動畫
如果使用xml方式定義補間動畫 要在res下創建一個anim目錄
alpha 透明度
<?xml version="1.0" encoding="utf-8"?>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
xmlns:android="http://schemas.android.com/apk/res/android">
</alpha>
rotate 旋轉
<?xml version="1.0" encoding="utf-8"?>
<rotate
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="360"
android:repeatMode="reverse"
android:repeatCount="1"
android:duration="2000"
xmlns:android="http://schemas.android.com/apk/res/android">
</rotate>
scale 縮放
<?xml version="1.0" encoding="utf-8"?>
<scale
android:fromXScale="1.0"
android:toXScale="2.0"
android:fromYScale="1.0"
android:toYScale="2.0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="reverse"
android:duration="2000"
xmlns:android="http://schemas.android.com/apk/res/android">
</scale>
translate 位移
<?xml version="1.0" encoding="utf-8"?>
<translate
android:fromXDelta="0%p"
android:toXDelta="0%p"
android:fromYDelta="0%p"
android:toYDelta="20%p"
android:fillAfter="true"
android:duration="2000"
xmlns:android="http://schemas.android.com/apk/res/android">
</translate>
集合 set
<?xml version="1.0" encoding="utf-8"?>
<set>
<!-- 屬性略-->
<alpha></alpha>
<rotate></rotate>
<translate></translate>
<scale> </scale>
</set>
調用
Animation aa = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha);
//開始執行動畫
iv.startAnimation(aa);
屬性動畫 Property Animation
屬性動畫會改變控件真實的座標
如果使用xml方式定義屬性動畫 要在res下創建一個animator目錄
代碼
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加載佈局
setContentView(R.layout.activity_main);
//作用 執行動畫
iv = (ImageView) findViewById(R.id.iv);
//給iv設置了一個監聽事件
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "你點不到我", 0).show();
}
});
//
// iv.setTranslationX(translationX)
// iv.setScaleX(scaleX)
// iv.setAlpha(alpha)
// iv.setro
}
//位移動畫
public void translate(View v){
//創建屬性動畫
/**
* target 執行的目標 誰執行動畫
* propertyName 屬性名字 The name of the property being animated.
* float... values 可變參數
*/
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 10, 50,20,150);
oa.setDuration(2000);
oa.start(); //開始動畫
}
//縮放動畫
public void scale(View v){
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);
oa.setDuration(2000);
oa.start();
}
//實現透明的效果
public void alpha(View v){
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1,0,1);
oa.setDuration(2000);
oa.start();
}
//實現旋轉的效果
public void rotate(View v){
// ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotation", 0, 180, 90, 360);
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);
oa.setDuration(2000);
oa.start();
}
//一起飛
public void fly(View v){
AnimatorSet as = new AnimatorSet();
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX", 10, 50, 20, 100);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "scaleY", 0.1f, 2, 1, 2);
ObjectAnimator oa3 = ObjectAnimator.ofFloat(iv, "alpha", 0, 0.5f, 0, 1);
ObjectAnimator oa4 = ObjectAnimator.ofFloat(iv, "rotationY", 0, 180, 90, 360);
as.setDuration(2000);
as.setTarget(iv);
//往集合中添加動畫
//挨個飛
as.playSequentially(oa, oa2, oa3, oa4);
//一起飛
// as.playTogether(oa, oa2, oa3, oa4);
as.start();
}
//使用xml的方式創建屬性動畫
public void playxml(View v){
ObjectAnimator oa = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.oanimator);
//設置執行目標
oa.setTarget(iv);
oa.start();//開始執行
}
}
xml實現
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android" >
<objectAnimator
android:propertyName="translationX"
android:duration="2000"
android:valueFrom="10"
android:valueTo="100"></objectAnimator>
</animator>
通知欄
通知用於在狀態欄顯示消息,消息到來時以圖標方式表示,
如果需要查看消息,可以拖動狀態欄到屏幕下方即可查看消息,
在Android 中通過通知管理器NotificationManager 來發出或關閉一個通知。
- 若設置了彈出通知會有聲音/震動/亮燈的效果,注意添加對應權限,否則會拋錯比如,設置震動需加權限android.permission.VIBRATE
- 獲取延期意圖PendingIntent 時,封裝的意圖對象必須採用隱式的方式
- startForeground(id, notification);可以提升進程優先級
public class MainActivity extends Activity {
private NotificationManager nm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]獲取NotificationManager 的實例
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
// 點擊按鈕發送一條通知
public void click1(View v) {
//鏈式調用
/* Notification noti = new Notification.Builder(this)
.setContentTitle("我是大標題")
.setContentText("我是標題的內容")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.build();*/
//兼容低版本的寫法 使用過時的方法
Notification notification = new Notification(R.drawable.ic_launcher, "我接收到了一條通知", System.currentTimeMillis());
//來一條通知 設置一下震動 讓呼吸燈亮
notification.defaults = Notification.DEFAULT_ALL;
//設置通知不讓清除
notification.flags = Notification.FLAG_NO_CLEAR;
//創建意圖對象
Intent intent = new Intent();
//實現撥打電話的功能
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+119));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
//點擊通知對應的業務邏輯
notification.setLatestEventInfo(this, "小芳", "老地方見", pendingIntent);
//發出通知
nm.notify(10, notification);
}
// 點擊按鈕 取消發送一條通知
public void click2(View v) {
//取消通知
nm.cancel(10);
}
}