安卓笔记-视频版(还没学完)

/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_WORLDstring>

在string.xml中添加键值对;也可以在调用的地方添加,例如按钮在Attributes的text属性右侧有三个点,点击此三个点即可选择已有键值对或添加新的键值对

name要小写

2、颜色资源 工程ResourceString

键值对放在color下:<color name="yhred">#FF0000color>

 

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">50dimen>

 

八、触屏事件:

工程TouchScreen

重写方法的快捷键 ctrl + o

on开头的方法一般都是回调方法:

1、触摸屏幕

    重写onTouchEvent方法

 

2、触摸屏幕上的某个控件

安卓事件分发机制详解:Android事件分发机制详解:史上最全面、最易懂太长了

 

九、线性与相对布局

《一》线性布局

LinearLayout:在一个方向上布局

1、orientation:方向:orientation 水平or竖直

2layout_gravity对齐方式:layout_gravity 左 右 中间 上 下对齐 默认左上对齐

3layout_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 leftArray new ArrayList();

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");

 

V4import 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(

                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 音量和闹铃

你可能感兴趣的:(移动,android,安卓)