/Users/yangyangzi/Desktop/YangZi2/android/Android12/2019/視頻學習.rtfd (公司電腦)
視頻
一、控件:TextView:標籤,用於顯示內容,內容不可編輯;Plain Text:內容可編輯;Button; imageView;imageButton:帶有點擊功能的圖片;checkBox複選框;RadioButton單選按鈕;radioGroup只能選一個
layout_width
一查看註釋方法:選中-》View-》Quick Documentation 快捷鍵F1
格式化代碼:Option + cmd +L
刪除整行:cmd + delete
光標到行首:cmd + <—
查找類:cmd+o
查看文件結構:cmd + F12
textStyle
textColor:安卓是十六進制顏色,需以#開頭
#RGB #F00(純紅)
#ARGB #FF00(純紅)
#RRGGBB #FF0000
#AARRGGBB #FFFF0000
二、Button繼承自TextView
響應點擊事件:在代碼裏註冊View.OnClickListener監聽器
註冊View.OnClickLister方法分以下三種:
內部類
匿名類
XML設置android:onClick
在activity中實現???
外部類的方式來實現???
三、EditText 繼承自TextView
inputType 輸入類型,小數點等
hint 即placeholder,輸入提示
android:singleLine="true" 單行輸入
android:background="@color/colorAlpha" 設爲透明,下劃線幾小時
四、imageView及ImageButton(ImageButton是ImageView的子類)
設置圖片:
1、在xml文件中設置是android:src
2、在代碼中設置是testIMV.setImageResource(R.mipmap.teacher_dev);
圖片與button小demo練習
android:scaleType="fitXY" 圖片的mode
五、選項控件
單選框:
RadioButton繼承自CompoundButton
isChecked();確定是否被選中
setChecked();強制選中或取消選中複選框
setOnCheckedChangeListener事件監聽
OnCheckedChangeListener事件回調
六、複選框
CheckBox
StringBuilder 可變字符串
七、資源的使用
1、字符串資源 工程ResourceString
字符串本地化或國際化
支持中文本地化:
在res/文件夾下創建名爲values-zh的文件夾,將res/values文件夾下的string.xml文件複製到新建的values-zh文件夾下。注意在values與values-zh文件夾下的string.xml文件裏的鍵必須是共同存在的,即前者有哪個鍵值對,後者也必須有相應的鍵值對,否則會報錯;注意:鍵不能重複,值能重複;注意鍵值對要放在reasource下
xml中取string.xml中字符串值:android:text="@string/yh_world"
代碼中取string.xml中的字符串值:buttonYh.setText(R.string.yh_world);
獲取resource資源:
Resources res = getResources();
通過resource資源獲取具體資源:
String fdd = res.getString(R.string.yh_world);
鍵值對放在string下:<string name="yh_world">YH_WORLD</string>
在string.xml中添加鍵值對;也可以在調用的地方添加,例如按鈕在Attributes的text屬性右側有三個點,點擊此三個點即可選擇已有鍵值對或添加新的鍵值對
name要小寫
2、顏色資源 工程ResourceString
鍵值對放在color下:<color name="yhred">#FF0000</color>
3、圖片資源 工程ResourceString
drawable文件夾下:buttonYh.setBackgroundResource(R.drawable.tefreshing01);
mipmap文件夾下:imageBtns.setImageResource(R.mipmap.tefreshing02);
在xml中引用圖片:android:roundIcon="@mipmap/ic_launcher_round"
圖片放在相應資源下
4、尺寸資源 工程ResourceString
一般用dp或sp做長度單位,與屏幕的物理長度無關
Xml中引用:android:layout_marginBottom="@dimen/yh_width"
鍵值對放在dimen下:<dimen name="yh_height">50</dimen>
八、觸屏事件:
工程TouchScreen
重寫方法的快捷鍵 ctrl + o
on開頭的方法一般都是回調方法:
1、觸摸屏幕
重寫onTouchEvent方法
2、觸摸屏幕上的某個控件
安卓事件分發機制詳解:Android事件分發機制詳解:史上最全面、最易懂太長了
九、線性與相對佈局
《一》線性佈局
LinearLayout:在一個方向上佈局
1、orientation:方向:orientation 水平or豎直
2、layout_gravity:對齊方式:layout_gravity 左 右 中間 上 下對齊 默認左上對齊
3、layout_weight權重:佔父控件的百分比;eg:兩個按鈕,各佔屏幕的50%,則兩個按鈕設置如下屬性值爲:layout_width=“0dp” layout_weight=”1“;
方式:gravity 文字對齊android:gravity="left"
當有layout_weight用法
orientation 爲 vertical時,則豎直方向的layout_height取值不起作用
orientation 爲 horizontal時,則水平方向的layout_width取值不起作用
java將int轉變爲string方法:
1、buttonView.getId() + ""
2、String.valueOf(buttonView.getId())
LinearLayoutTest工程有問題???,待解決
java中的 a |= b 即 a = a || b
CheckBox的setChecked的方法中調用了onCheckedChanged方法
2019.2.15
《二》相對佈局RelativeLayout:
1、相對於容器; 工程RelativeLayout
layout_alignParentTop = "true"
layout_alignParentBottom = "true"
layout_alignParentLeft = "true"
layout_alignParentRight = "true”
layout_centerInParent = "true"
2、相對於控件; 工程RelativeLayout
根據id做控件對齊依據
layout_above="@id/button1" 其下邊與button1的上邊挨着
layout_below="@id/button1" 其上邊與button1的下邊挨着
layout_alignLeft="@id/button1" 其與button1的左邊對齊
layout_alignTop="@id/button1" 其與button1的上邊對齊
layout_toLeftOf="@id/button1" 其右邊與button1的左邊挨着
layout_toRightOf="@id/button1" 其左邊與button1的右邊挨着
3、基線對齊 工程RelativeLayout2
layout_alignBaseline="@id/rightET" 與rightET的底部基線對齊
2019.2.18
佈局公有屬性
Padding:控件的內容與控件邊緣的距離;
Margin:控件與控件的相對距離;包括子控件與父控件邊緣距離
線性與相對佈局的嵌套使用:工程LinearAndRelative
字體大小:textSize
子視圖在俯視圖的佈局:margin
LayOut文件出問題,不報錯,卻運行不了,太坑了,寫錯了也不知道,太坑
嵌套原則:層數越少約好,越簡單約好
《三》表格佈局:TableLayout
1》、在行中添加單元格TableRow:
android:layout_column="2" 指明列數
android:layout_span="2" 橫向合併列
沒有添加tableRow的情況,則一個控件佔一行
注意:一個TableviewLayout有幾行是根據TableRow的個數決定的
而有每個TableRow有幾列不是其本身的TableRow上控件個數決定的,而是由其上下文決定的,即看此TableLayout中哪個TableRow的控件個數最多,按這個最多的TbaleRow的控件個數決定
2》、擴展、收縮和摺疊
擴展:android:stretchColumns="1" 第一列可以擴張,佔tableRow剩下的所有寬度
收縮:android:shrinkColumns="1" 內容長時第一列可以收縮自動換行
摺疊:android:collapseColumns="1" 隱藏第一列
只能合併列,不能合併行
《四》網格佈局:GridLayout
可以設置
組件的排列方式:android:orientation="vertical”默認是horizontal
行數:android:rowCount="6"
列數:android:columnCount="4"
合併兩行:android:layout_rowSpan="2"
合併三列:android:layout_columnSpan=“3”
填充合併的行或列:android:layout_gravity="fill”(layout_gravity還可以取值center/left/right/buttom及相應的_horizontal和_vertical)
《五》幀佈局:FrameLayout 三星
顯示的控件都會放在屏幕左上角,不能指定位置
當有多個顯示對象,後一個將會遮蓋住前一個
《六》佈局:DrawerLayout 一星
能實現DrawerLayout效果的關鍵是:android:layout_gravity = "start"
android:gravity:是對view控件本身來說的,是用來設置view本身的內容應該顯示在view的什麼位置,默認值是左側。也可以用來設置佈局中的控件位置;
表示當前View,即控件,內部的東西的,對齊方式
.android:layout_gravity:是相對於包含該元素的父元素來說的,設置該元素在父元素的什麼位置;
表示當前View,即控件本身,在父一級內的對齊方式
gravity與layout_gravity的區別:https://www.cnblogs.com/fuck1/p/5461952.html
《七》佈局:ScrollVIew 一星 extens FrameLayout
ScrollView和HorizontalScrollView只能有一個子控件,一般會放個LinearLayout
ScrollView用於設置垂直滾動條;HorizontalScrollView用於設置水平滾動條
隨意
2019.2.19
消息處理機制
主線程超過5秒爲響應,則系統會彈ANR框報錯 Sorry 。。。is not
responding
一、消息隊列
消息循環產生消息隊列
Activity用消息隊列(Message Queue)機制保證線程間通信
消息隊列用來存放Handler發佈的消息
安卓在程序第一次啓動時會默認爲UI線程(主線程)創建一個關聯消息隊列,用來管理程序的組件,如Activity,Service,Broatcast Receiver等
不同線程用Handler來使子線程和主線程通信
可以在子線程(工作線程中)創建Handler與主線程通信
主線程創建looper,looper裏存放消息隊列,消息隊列裏存message
二、Handler的消息傳遞機制 工程MessageRules
1、子線程通過Handler與主線程通訊
2、Handler對象的所有工作將在主線程中執行
3、Handler需要實現handleMessage()方法,來處理消息隊列中去除的Message對象
4、handleMessage()方法由主線程調用,可以在需要的時候更新UI界面。但是,必須確保此方法快速完成,因爲其他UI操作會等待它完成才能執行
5、可以在Message中附加不同參數 water標示;avg1,avg2傳遞int類型數據;obj傳遞對象類型的數據
三、Handler的編程接口
方法
void handleMessage(Message message) 在主線程處理消息
boolean sendEmptyMessage(int what) 發送空消息,此參數是一個消息標示
boolean sendMessage(Message message) 發送消息到Handler中,在handleMessage中處理
boolean hasMessage(int what) 判斷是否有what消息
boolean post(Runnable r) 將一個Runnable添加到消息隊列
XML的解析:
1、xml文件放在res/xml目錄下,注意res下默認沒有xml文件夾,需要手動創建該文件夾,若果單純放在res文件夾下回報錯
2、xml文件在部署時將被編譯爲有效的二進制文件
3、根據需要可以自定義xml結構
4、安卓使用pull方式解析xml,本事是SAX解析(事件驅動,需要知道事件)
XMLPullPaser
寫示例
Java的拋異常機制???
效率好低啊
JSON解析
在res文件夾下新建raw文件
期初加入到raw文件夾下的文件名爲parJson.json,後報錯,把文件名的大寫J改爲小寫j即可
線程使用場景:解析xml並展示在listView上
工程:SimpleAdapterTest
1、onCreate方法中,創建子線程,並在子線程中添加要執行的異步操作(在run方法中),解析完文件,通過sendmessage回到主線程:
new Thread(){
@Override
public void run() {
try {
parseXml();
handler.sendEmptyMessage(what);
} catch (XmlPullParserException e) {
handler.sendEmptyMessage(lala);
// e.printStackTrace();
} catch (IOException e) {
handler.sendEmptyMessage(lala);
// e.printStackTrace();
}
};
}.start();
2、回到主線程在,handler的handleMessage方法將得到的數據複製到主線程的listview
注意:不能再子線程處理控件,否則報錯,需要回歸到主線程再操作主線程
2.21 StringBuilder的.append(name)方法,傳參不能爲空
控件
消息提示Toast:
彈出Toast:短暫彈框,不用用戶響應
靜態方法:makeText()
構造函數:new ;setView();setDuration()
自定義Toast:通過LayoutInflater.from加載自定義view
View tview = LayoutInflater.from(this).inflate(R.layout.toast_self_defined_view, null);
AlertDialog:通過Builder創建,鏈式語法.set設置:
1》提醒框: AlertDialog
以下對話框都是AlertDialog,只是參數不同:
列表對話框:
2》單選列表對話框:AlertDialog
.setSingleChoiceItems(ddArray, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.d("TEST", "" + which + "");
}
})
3》多項選擇列表對話框;AlertDialog
.setMultiChoiceItems(sdff, new boolean[]{false, true, true}, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
Log.d("TEST", which + "," + isChecked);
}
})
4》普通列表對話框 AlertDialog
無.setxxChoiceItems()方法
進度條對話框:ProcessDialog(圓圈或長條)
自定義對話框:工程SelfDefinedDialog
方式一:產生一個Dialog類實例:setContentView(View view)設置自定義的視圖:
twoDialog = new Dialog(this);
twoDialog.dismiss();
方式二:使用AlertDialog.Builder創建AlertDialog實例:setView(View view)設置自定義視圖;.create()創建對象 工程 SelfDefinedDialog
內部類要用到外部類的局部變量,需要用final修飾此局部變量
2019.2.25
適配器:Adapter
負責爲選擇部件提供數據源,也負責將單獨的數據元素轉換爲顯示在選擇部件中的特定視圖
ArrayAdapter的三個參數:(安卓系統寫好的適配器)
參一:上下文,通常是當前activity的實例
參二:使用的視圖資源的ID
參三:要實際顯示的選項數組或列表
列表:ListView
示例工程:AdapterAndListview
ArrayAdapter arrayAdapter = new ArrayAdapter(
this,
android.R.layout.simple_list_item_1,
android.R.id.text1,
data
);
listView.setAdapter(arrayAdapter);
SimpleAdapter:將xml解析並賦值給listview
listView = findViewById(R.id.listview);
SimpleAdapter simpleAdapter = new SimpleAdapter(
this,//上下文
data,//數據源
R.layout.list_item,//項佈局
new String[]{"name","age"},//顯示數據在數據源中的key
new int[] {R.id.leftTV, R.id.rightTV }//顯示數據的控件id
);
listView.setAdapter(simpleAdapter);
private static final int what = 1001; 修飾詞這麼多
BaseAdapter:
工程:BaseAdapterTest
BaseAdapter 只是一個父類,在使用時需要創建繼承自BaseAdapter的子類
ListView提高效率(相當於ios的cell重用機制);
工程:BaseAdapterAndEfficientTest 2.26
與public View getView(int position, View convertView, ViewGroup parent) {}方法的covertView參數相關的重用機制,
獲得自定義xml的解析方法是dom解析,此種解析方法每次解析都會將文件放入內存,如果沒有使用重用機制就太浪費空間了,故我們在這創建了一個ViewHolder持有者,對自定義xml的子控件進行緩存持有。
此例用count值查看是否重用了;
ListView提高效率:使用ConterView+使用持有者模式
GridView:網格控件與上邊的ListView相似(ios的collectionview)
與listview一樣都是選項控件,用適配器:
verticalSpacing:垂直間距
GridView隨着數據的刷新而更新:工程AdapterRefresh (數據更新reload;按鈕的點擊事件寫法3:視頻裏extends Activity;而現在AS是extends AppCompatActivity,故這種事件點擊方式不適用AS
public class AdapterRefresh extends AppCompatActivity implements OnClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addBtn.setOnClickListener(this);
}})
String name = editText.getText().toString().trim();
方法trim()的作用:去掉字符串收尾的空格
通知數據修改Adapter的notifyDataSetChanged()方法
Spinner:顯示下拉式內容,顯示多項內容的選擇控件
工程:SpinnerTest
1》通過Adapter添加數據 topSpinner.setAdapter()
2》在xml文件中通過屬性entries添加字符串資源中數組添加數據 android:entries="@array/name_string_array"
進階:聯動spinner(班級:學生級聯菜單)工程SpinnerTest(自己寫的有問題) + 工程SpinnerLianDongTest(視頻的)
注:開始自己寫的工程SpinnerTest來演示聯動spinner,總是編譯不過,經過各種嘗試,發現是泛型使用不規範引起的,看來java對泛型的要求很高啊,以後凡是數組一定要加上泛型(ios在泛型這塊就沒那麼苛刻了)
java數組:
private List <String>leftArray = new ArrayList<String>();
leftArray.add("安卓");
leftArray.add("蘋果");
與
private String[] leftArray = {"安卓", "蘋果"};
有啥區別?
前者是集合,後者纔是數組待java書到之後細研究
Activity配置:
四大組件之一;組件必須在AndroidManifest.xml中說明才能使用
AndroidManifest.xml文件中的
1、package="com.example.yangyangzi.spinnertest”是包名
<activity android:name=".SpinnerTest"> 此處是類名
2、<activity android:name=".SecondActivity"
android:label="第二個Activity"></activity>
此處的android:label默認是
<application
android:allowBackup="true"
android:label="@string/app_name”>處的label
Activity之間的跳轉:
通過intent跳轉:
顯式跳轉:通過目標Activity名稱跳轉
Intent intentt = new Intent(this,SecondActivity.class);
startActivity(intentt);
或
{
// Intent intent = new Intent();
// intent.setClass(this,SecondActivity.class);
// startActivity(intent);
}
隱式跳轉:通過activity的邏輯動作名跳轉,可以不暴露目標Activity的名稱
AndroidManifest.xml:
<activity android:name=".ThirdActivity"
android:label="第三個Activity">
<intent-filter>
<!--自定義邏輯動作名-->
<action android:name="yhaction"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Intent intent = new Intent();
intent.setAction("yhaction");
startActivity(intent);
Activity間通訊:
啓動Activity:startActivity;startActivityForResult:啓動過程有返回
通過:intent.putExtras(Bundle); intent.putExtra(key,value);傳值到另一個組件
接收:目標組件通過getIntent()得到intent,通過getExtras方法得到所傳的對象
工程:ActivityPassSomething
Activity返回值:
開始Activity:
startActivityForResult() 啓動Activity
onActivityResult() 接收目的Activity返回的數據
目標Activity:
setResult(code,intent); 目標Activity設置返回的內容
Activity生命週期:示例工程:LifeOfActivity
onCreate創建,在整個生命週期只調用一次
onStart加載到內存,Activity不可見,啓動
onResume顯示,Activity可見
onPause失焦點,Activity可見,但是不能操作
onStop被其他Activity蓋掉,Activity不可見,未銷燬
onDestory 在整個生命週期只調用一次,
點back則onDestory了
線程Thread中,返回到主線程的另一方法:
線程的終止居然用boolean屬性值和死循環實現
new Thread(){
@Override
public void run() {
count++;
handler.post(new Runnable() {
@Override
public void run() {
//運行在主線程中
textView.setText("" + count);
}
});
}
}.start();
Activity的啓動模式:4種launchMode
在AndroidManifest.xml中設置模式launchMode:
<activity android:name=".SingleInstanceActivity"
android:label="SingleInstanceActivity"
android:launchMode="singleInstance"
></activity>
1、standard(默認):每次激活Activity都會重新創建,並放入任務棧中
2、singleTop:如果在任務的棧頂正好存在該Activity的實例,就會重用該實例,而不會重新創建新的Activity對象,不過它會調用onNewIntent()方法;如果棧頂不存在就會創建新的實例並放入棧頂(即使棧中已經存在該Activity實例,只要不在棧頂,都會創建實例)。不會調用onNewIntent()方法
注:Activity中this.toString()結果 一般都是包名+@+16進制字符串
3、singleTask:如果在棧中有改Activity實例,就重用該實例(會調用實例的onNewIntent()方法);
重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧。
如果棧中不存在該實例,將會創建新的實例放到棧中
在棧中只有一個
4、singleInstance:與singleTask模式的區別是存放singleInstance模式窗口對象的回退棧不能有其他任何窗口對象。因此如果該窗口不存在,則要新建任務來存放該singleInstance窗口???
即創建了一個新的棧,可以理解爲單例模式
單例的理解如下圖:
對上圖的解釋(也是singleInstance模式的精髓)
現在有兩個Activity,即MainActivity(除SingleInsatnce模式以外的其他模式)和SingleInstanceActivity(SingleInstance模式):
由MainActivity跳到SingleInstanceActivity(創建新的SingleInstanceActivity),
再由SingleInstance跳到MainActivity(創建新的MainActivity),
再由MainActivity跳到SingleInstanceActivity(用舊的SingleInstanceActivity),
再由SingleInstance跳到MainActivity(創建新的MainActivity),三
再由MainActivity跳到SingleInstanceActivity(用舊的SingleInstanceActivity) 四
注意以上跳轉是互相調用而非返回
MainActivity無論屬於哪種模式在這種情況,按正常走都得新建;SingleInstanceActivity因爲是SingleInstance模式的只用新建一次(跟單例差不多)
接下來,在上邊操作步驟基礎上,
做回退操作(當前在SingleInstanceActivity裏即從四開始回退):
在SingleInstanceActivity時點擊返回按鈕,退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,退到桌面
SingleInstance回退一次,在回退則進入正常的任務棧,將此棧的所有Activity銷燬後,之後再點一次返回則退到home
做回退操作(當前在MainActivity裏即從三開始回退):
在MainActivity頁面點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到MainActivity,
再點返回按鈕,還是退到SingleInstanceActivity,
再點返回按鈕,退到桌面
說明先是把正常的任務棧的所有Activity銷燬後再點返回纔會跳到SingleInstance模式的Activity,之後再點一次返回則退到home
注:finish()與點返回按鈕當前Activity都被從任務棧中移除
棧id:棧的唯一標識符
靈活使用四種Activity模式可以節約系統資源
Fragment的生命週期和使用:
Fragment是在Android3.0(API level 11)開始引入新的API技術。
爲提高代碼重用性和改善用戶體驗,我們將Activity中的UI組件進行分組和模塊化管理。這些分組後的UI組件就是Fragment。
一個Activity可以包含多個Fragment模塊,而同一個Fragment模塊也可以被多個Activity使用。
每個Fragment有自己的佈局,有自己是生命週期。
我們可以設計Fragment的佈局
Fragments必須放在一個Activity中,
Fragments有自己的生命週期,而且受到它所在宿主Activity是聲明週期的影響
Fragmens可以接收它自己是事件
一個Fragment可以放在多個Activity中,一個Activity也可以放置多個Fragments
Fragment的生命週期:
創建一個Fragment需要實現是回調函數:
onCreate():創建Fragment時系統會調用此函數
onPause():當用戶離開當前Fragment時調用此方法。通常用來保存持久化數據
OnCreateView():當Fragment第一次繪製它的UI時調用。這個方法必須返回一個View,表示這個Fragment的根佈局
創建Fragment,如果用到早期的Android系統如2.2,2.3則需要繼承自android.support.v4.app.Fragment()即minSdkVersion<11時繼承自v4 jar包;其他直接繼承自系統的Fragment的jar包,安卓3.0以上
Fragment的生命週期:
[Fragment is added]->onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->[Fragment is active]->1、/2、->onPause()->onStop()->onDestoryView()->onDestory()->onDetach()->[Fragment is destoryed]
Fragment的生命週期和Activity做比較:
(一)運行-》界面出現 (MyFragmentMyFragment是Fragment;ActivityMyFragment是Activity)
MyFragmentMyFragment: onCreate
MyFragmentMyFragment: onCreateView
ActivityMyFragment: onCreate
ActivityMyFragment: onStart
MyFragmentMyFragment: onStart
ActivityMyFragment: onResume
MyFragmentMyFragment: onResume
Fragment的onCreate->Activity的onCreate->Activity的onStart->Fragment的onStart->Actvity的onResume->Fragment的onResume
工程界面-》home鍵(Activity不銷燬)-》桌面
MyFragmentMyFragment: onPause
ActivityMyFragment: onPause
MyFragmentMyFragment: onStop
ActivityMyFragment: onStop
Fragment的onPause->Activity的onPause->Fragment的onStop->Activtiy的onStop
桌面-》工程界面
ActivityMyFragment: onStart
MyFragmentMyFragment: onStart
ActivityMyFragment: onResume
MyFragmentMyFragment: onResume
Activity的onStart->Fragment的onStart->Activty的onResume->Fragment的onResume
工程界面-》返回鍵(Activity銷燬)-》桌面
MyFragmentMyFragment: onPause
ActivityMyFragment: onPause
MyFragmentMyFragment: onStop
ActivityMyFragment: onStop
MyFragmentMyFragment: onDestroy
ActivityMyFragment: onDestroy
Fragment的onPause->Activty的onPause->Fragment的onStop->Activity的onStop->Fragment的onDestory->Activity的onDestory
返回後桌面-》工程界面
MyFragmentMyFragment: onPause
ActivityMyFragment: onPause
MyFragmentMyFragment: onStop
ActivityMyFragment: onStop
ActivityMyFragment: onStart
MyFragmentMyFragment: onStart
ActivityMyFragment: onResume
MyFragmentMyFragment: onResume
Fragment的生命週期和Activity非常相似,一個Fragment可以處於3種狀態:
運行:Fragment在當前運行的前臺,Activity中可見
暫停:另一個Activity在前臺,具有焦點,但是Fragment所在的Activity依然可見
停止:Fragment不可見。宿主Activity處於停止狀態或Fragment已經從Activity刪除並添加到後臺棧中。
Framment的宿主Activity的生命週期直接影響Fragment的生命週期。因此,Activity的每個生命週期回調函數都會調用Fragment的回調函數。例如,當宿主Activity的onPause()方法被調用時,Fragment的onPause()方法也被調用。
(二)Fragment還有一些其他的回調函數與宿主Activity交互,處理UI的創建與銷燬。
onAttach()當Fragment與Activity建立關聯時調用,Activity作爲參數傳入;
onCreateView()創建Framgment的UI;
onActivityCreated()當Activity的onCreate()方法返回時調用;
onDestoryView()當Fragment的UI被刪除時調用;
onDetach()當Frament與Activty取消關聯調用;
加入以上四個Fragment的方法後的運行順序爲:
運行-》工程界面:
MyFragmentMyFragment: onAttach
MyFragmentMyFragment: onCreate
MyFragmentMyFragment: onCreateView
ActivityMyFragment: onCreate
MyFragmentMyFragment: onActivityCreated
ActivityMyFragment: onStart
MyFragmentMyFragment: onStart
ActivityMyFragment: onResume
MyFragmentMyFragment: onResume
工程界面-》back-》桌面:
MyFragmentMyFragment: onPause
ActivityMyFragment: onPause
MyFragmentMyFragment: onStop
ActivityMyFragment: onStop
MyFragmentMyFragment: onDestroyView
MyFragmentMyFragment: onDestroy
MyFragmentMyFragment: onDetach
ActivityMyFragment: onDestroy
無論是home還是back後的桌面-》工程界面都和(一)相同
Fragment的生命週期:
當宿主Activity處於運行狀態時,可以自由添加和刪除Fragment。只有Activity處於運行狀態時,Fragment的聲明週期才能獨立變化。否則,直接受宿主Activity聲明週期的影響
3.4Frament交互及管理
1》FragmentManager API:工程FragmentManagerTest
APP:import android.app.FragmentManager;
獲取FragmentManager:manager = getFragmentManager();
獲取Fragment:fragmentDemo = (FragmentDemo) manager.findFragmentById(R.id.myfragment);
fragmentDemoOne = (FragmentDemo)manager.findFragmentByTag("YHLL");
V4包:import android.support.v4.app.FragmentManager;
獲取FragmentManager:manager = getSupportFragmentManager();
獲取Fragment:v4FragmentDemo = (V4FragmentDemo)fragmentManager.findFragmentById(R.id.v4fragment);
manager.findFragmentByTag("YHLL");
v4FragmentDemoTwo = (V4FragmentDemo)fragmentManager.findFragmentByTag("v4fragmentTwo");
2》FragmentTranscation API(動態添加Fragment,以前的都是靜態添加的):工程FragmentTranscationTest
add():向容器中添加一個Fragment
remove():刪除Fragment
replace():將容器中的Fragment替換成新的Fragment
hide():隱藏已存在的Fragment
show():顯示此前隱藏的Fragment
addToBackStack():將事務添加到後臺棧
commit():提交事務,將改變應用到Activity
.replace()替換Fragment(注意:不能替換本Fragment只能是替換另一個不同類型的Fragment)
添加Fragment:
FragmentManager manager = getFragmentManager();//1、獲取FragmentManager
FragmentTransaction transaction = manager.beginTransaction();//2、通過FragmentManager獲取FragmentTransaction事物
MyFragment myFragment = new MyFragment();//3、創建Fragment
transaction.add(R.id.frameLayout,myFragment,"he");//4、將上邊的Fragment添加到FragmentTransaction事物
transaction.commit();//5、提交事物
替換Fragment:
//添加到返回棧中,點返回按鈕則依次返回,最後退到桌面,不添加返回棧的則直接退到桌面
getFragmentManager().beginTransaction().replace(R.id.frameLayout,numFragment).addToBackStack(null).commit();
靜態方法(類方法);靜態成員變量(類成員變量ios無);工程JavaTest
3》系統提供的Fragment類開發者可以繼承:實現了Fragment類的子類
DialogFragment:顯示一個懸浮對話框 工程:DialogFragmentTest
好像和AlertDialog差不多啊,爲麼還要費事用DialogFragment???
DialogFragmentTest.this.showToast();//成員方法調用showToast()實例方法
((DialogFragmentTest)getActivity()).showToast();//getActivity()調的是FragmentActivity
java:
非靜態方法可以訪問靜態方法;而靜態的不能訪問非靜態的 非靜態>靜態 對比ios的工程:testLei
靜態與非靜態之間的互相調用 DialogFragmentTest-TestStatic類
public statc class MyDialogFragment extends DialogFragment{
public static MyDialogFragment newInstance (String tittle){//初始化帶參靜態方法
MyDialogFragment myDialogFragment = new MyDialogFragment();
Bundle bundle = new Bundle();
bundle.putString("title",tittle);
myDialogFragment.setArguments(bundle);
return myDialogFragment;
}
public Dialog onCreateDialog(Bundle savedInstanceState) {//創建AlertDialog彈窗
tittle = getArguments().getString("title");
Dialog dlog = new AlertDialog.Builder(getActivity())
.setTitle(tittle)
.setIcon(R.mipmap.ic_launcher)
.setPositiveButton("確定", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
((DialogFragmentTest)getActivity()).showToast();
}
})
.setNegativeButton("取消",null)
.create();
return dlog;
}
}
ListFragment:顯示一個由adapter管理的項目列表
public void showListFragmentAction(View view){
String[]data = {"AAA","BBB","CCC"};
MyListFragment myListFragment = MyListFragment.newInstance(data);
getFragmentManager().beginTransaction()
.add(R.id.fatherLayout,myListFragment)
.commit();
}
public static class MyListFragment extends ListFragment {
public static MyListFragment newInstance(String[] data){
MyListFragment myListFragment = new MyListFragment();
Bundle bundle = new Bundle();
bundle.putStringArray("data",data);
myListFragment.setArguments(bundle);
return myListFragment;
}
@Override
public void onAttach(Context context) {//設置適配器
super.onAttach(context);
String[] data = getArguments().getStringArray("data");
setListAdapter(new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
data
));
}
@Override
public void onListItemClick(ListView l, View v, int position, long id){//重新onListItemClick方法,響應點擊事件
Toast.makeText(getActivity(),data[position],Toast.LENGTH_LONG).show();
super.onListItemClick(l, v, position, id);
}
}
Fragment如果是動態添加到宿主Activity,則不一定和Acitivity聲明週期相關
3.11
Fragment總和應用(一)
支持平板和手機 工程名:FragmentAdaptePhoneAndPad 3月文件夾
v4包的Activity繼承自FragmentActivity
另一種Activity繼承自Activity
接口:
FragmentAdaptePhoneAndPad->MyJieKou
FragmentAdaptePhoneAndPad->SelectCityListener
FragmentAdaptePhoneAndPad->FatherJieKou
接口之間的繼承;類在實現多個接口
適配橫豎屏*** layout-land
爲了避免在一個Fragment中出現調用另外一個避免耦合嚴重,應該定義回調接口,需要宿主Activity實現這個接口。這樣在Fragment接收到事件的時候,調用這個接口中的方法讓Activity根據具體的配置做出響應
Fragment總和應用(二)
ViewPager 在supportv4中:一般和Fragment使用,也可以和view使用;在3.0以下版本只能用view,以上版本用Fragment配合使用,官方(谷歌)推薦使用Fragment
<android.support.v4.view.ViewPager
android:layout_width=""
android:layout_height=""></android.support.v4.view.ViewPager>
佈局解析器inflater:LayoutInflater inflater = LayoytInflater.from(this);
viewPager對象設置適配器:PagerAdapter(是一個抽象類)
以view爲子視圖工程:ViewPagerTest 抽象類是PageAdapter
//給ViewPager對象設置適配器PageAdapter
viewPager.setAdapter(new MyPageAdapter());
public class MyPageAdapter extends PagerAdapter{
@Override
public int getCount() {
return views.length;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
return view == o;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(views[position]);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
container.addView(views[position]);
return views[position];
}
}
以Fragment爲子視圖工程:ViewPagerTestAgain 抽象類是專門用於Frament的FragmentPagerAdapter
viewPager.setAdapter(new MyPageAdapater(getSupportFragmentManager()));
class MyPageAdapater extends FragmentPagerAdapter {
public MyPageAdapater(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
return fragments[i];
}
@Override
public int getCount() {
return fragments.length;
}
}
注意:
1》view和Fragment分別做子類時,其viewpager對象的適配器PageAdapter不同,但都是繼承自抽象類PageAdapter的自定義抽象類;
2》抽象類需要實現的方法不完全相同;
3》Viewpager設置適配器的構造方法的參數有差別
2019.3.12
ViewPager的總和運用(三)FragmentThreeTest
使用ViewPager實現基本導航,即不隨ViewPager而滾動
Viewpager:
設置當前子控件:viewPager.setCurrentItem(item);
滑動及選中事件:viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {//正在滾動
}
@Override
public void onPageSelected(int i) {//已經改變
selectTittle(i);
}
@Override
public void onPageScrollStateChanged(int i) {//滾動狀態發生改變
}
});
ViewPager的總和運用(四)工程:FragmentFourTest(自己寫的) 工程:FragmentThreeTest的副本(視頻關鍵位置運用)
歡迎界面:
選擇器的創建和使用(FragmentThreeTest的副本):
在drawable文件夾下新建文件dot.xml(new -file -Drawble Resource File-dot.xml選擇selector)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:drawable="@drawable/raidono"></item>//選中狀態是圖片raidono
<item android:state_enabled="false" android:drawable="@drawable/raidoselec"></item>//非選中狀態是圖片raidoselec
</selector>
圖片在使用時,則src如下:(dot爲上邊創建的xml的文件名)
<ImageView
style="@style/tab_style"
android:src="@drawable/dot"
/>
爲何selector的圖片只能放在drawable文件夾下??不做圖片適配麼?
ActionBar:(Fragment綜合使用五)工程:ActionBarVSFragmentFiveTest
使用ActionBar來創建tab步驟,則滑動效果自然就有了
啓用NAVIGATION_MODE_TABS
創建幾個ActionBar.Tab的實例
對每個實例實現ActionBar.TabListener接口
2019.3.13
DrawerLayout :(抽屜式導航 Fragment綜合使用五)工程:DrawerLayoutVSFragmentTest
自定義控件:
按類型劃分,自定義View的實現方式可分爲三種:
自繪控件:工程 SelfDefinedControlDraw
View上所展示的內容全部是繪製出來的;
繪製代碼寫在onDraw()方法中的;
自定義在View界面上顯示,只需要像普通控件一樣使用自定義view即可
示例:圈;長方形;圖片
<com.example.yangyangzi.selfdefinedcontroldraw.DrawView //包名+類名
android:layout_width="match_parent"
android:layout_height="match_parent" />
移動的自定義view 工程:SelfDefinedControlInvalidate
view的刷新
組合控件:工程CollectionSelfDefinedControl
XML組合控件;代碼組合控件
繼承控件:工程ExtendsSelfDefinedControl
3.14 Service
是一種Android的組件,可以在後臺長時間運行
不提供交互界面:
即便用戶跳轉至另一個應用後,service仍在後臺運行
任意應用組件都可以綁定服務,甚至可以用來完成進程間通訊的任務,例如 需要下載時;播放音樂;文件I/o
3.15 工程:ServiceTest
1>單獨的服務:
創建service file-》new service
啓動服務:
intent = new Intent(this,MyService.class);
startService(intent);
停止服務:
intent = new Intent(this,MyService.class);
stopService(intent);
重寫服務的方法:
onCreate;onDestroy;onStartCommand;onBind
點擊start按鈕:
onCreate
onStartCommand
點擊stop按鈕:
onDestroy
再點擊start按鈕:
onCreate
onStartCommand
再點擊start按鈕:
onStartCommand
注意:如果啓動服務再次啓動服務,則會調用onStartCommand方法
2>和應用關聯的服務:
創建service file-》new service
啓動服務:
intent = new Intent(this,MyService.class);
bindService(intent, conn, BIND_AUTO_CREATE);//bindService必須要有個連接的存在,如果不存在BIND_AUTO_CREATE參數指示自動創建
停止服務:
intent = new Intent(this,MyService.class);
unbindService(conn);
重寫服務的方法:
onCreate;onDestroy;onStartCommand;onBind
點擊bind按鈕:
onCreate
onBind
onServiceConnected(Activity中)
點擊unbind按鈕:
onDestroy
再點擊bind按鈕:
無反應
再點擊start按鈕:
無反應
注意:如果要Activity的ServiceConnection的回調方法響應,必須在onBind方法中創建並返回繼承自Binder的類
工程:BindServiceTest 用bind的service計算平均分,並顯示在界面上
內部類方法可以調用外部類方法,反之不可
工程:StartServiceTest 用startService的方法計算平均分,只能在sevice計算,不能單純返回到activity,以後可以用廣播的方式返回並展示
系統服務:
由於是Android原代碼,可以通過Android代碼來對服務進行交互
Android將Binder封裝成普通的Manager類,代碼調用時無法察覺是使用了Service
這些服務通過Context.getSystemService(String name)來獲得,name決定了獲得不同的Mananger類,不同的Manager類有各自的方法來調用系統功能或是訪問系統狀態
例如:
電源管理:POWER_SERVICE
NotificationManager通知的管理:NOTIFICATION_SERVICE
LocationManager定位的控制:LOCATION_SERVICE
ConnectionManager網絡連接的控制:CONNECTIVITY_SERVICE
示例:SystemServiceTest 音量和鬧鈴