Android四大组件之-Activity的创建与应用

文章目录

一、Activity的创建与生命周期

1.Activity的创建

1.创建一个layout xml布局文件
2.创建一个java类继承Activity或者AppCompatActivity
3.重写onCreate()方法,在onCreate()方法中调用setContentView()方法设置要显示的layout文件
	@Override
	protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.activity_main); 
	}
4.在AndroidManifest.xml文件中注册Activity
	<activity android:name=".MainActivity2"></activity>

做完以上4步就已经完成了一个Activity的创建,Android Studio工具还提供了更快捷的方法,直接鼠标右键-new - Activity - 选择任意一种布局的activity - 重命名一下Activity Name和Layout Name点击Finish完成创建。

2.Activity的生命周期

1.启动activity时依次调用:onCreate,onStart,onResume
2.按back键时依次调用:onPause,onStop,onDestroy
3.按home键或者跳转到其他页面时依次调用:onPause,onStop
4.从其他页面按back键返回时依次调用:onRestart,onStart,onResume
5.横竖屏切换时依次调用: onPause ,onStop, onDestroy,onCreate, onStart,onResume

从activity1跳转到activity2时依次调用:
activity1的onPause
activity2的onCreate
activity2的onStart
activity2的onResume
activity1的onStop

从activity2按back键返回activity1时依次调用:
activity2的onPause
activity1的onRestart
activity1的onStart
activity1的onResume
activity2的onStop
activity2的onDestroy

可复制以下代码运行,自行查看log打印确认

MainActivity.java

public class MainActivity extends AppCompatActivity {
    	TextView bt;
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
        	super.onCreate(savedInstanceState);
        	setContentView(R.layout.activity_main);
        	Log.d("MainActivity", "onCreate()");
    	}
    	
    	@Override
   	 	protected void onStart() {
        	super.onStart();
        	Log.d("MainActivity", "onStart()");
   	 	}
   	 	
    	@Override
   	 	protected void onStop() {
        	super.onStop();
        	Log.d("MainActivity", "onStop()");
    	}
    	@Override
    	protected void onDestroy() {
        	super.onDestroy();
        	Log.d("MainActivity", "onDestroy()");
    	}

    	@Override
    	protected void onPause() {
        	super.onPause();
        	Log.d("MainActivity", "onPause()");
   		}

    	@Override
    	protected void onResume() {
        	super.onResume();
       	 	Log.d("MainActivity", "onResume()");
        	bt = (TextView) findViewById(R.id.bt);
       	 	bt.setOnClickListener(new View.OnClickListener() {
            	@Override
            	public void onClick(View v) {
                	Intent it = new Intent(MainActivity.this, MainActivity2.class);
                	startActivity(it);
            	}
       		 });
    	}

    	@Override
    	protected void onRestart() {
        	super.onRestart();
        	Log.d("MainActivity", "onRestart()");
    	}
	}

MainActivity2.java

public class MainActivity2 extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Log.d("MainActivity2", "onCreate()");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("MainActivity2", "onStart()");
   	}

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("MainActivity2", "onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("MainActivity2", "onDestroy()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("MainActivity2", "onPause()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("MainActivity2", "onResume()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("MainActivity2", "onRestart()");
    }
}

二、layout布局常用控件用法与详解

Android中有六大布局,分别是: LinearLayout(线性布局),RelativeLayout(相对布局),TableLayout(表格布局) FrameLayout(帧布局),AbsoluteLayout(绝对布局),GridLayout(网格布局) 。
实际运用中,LinearLayout和RelativeLayout用的最多。

1.线性布局

 <LinearLayout
    android:layout_width="match_parent" 		//设置该组件的宽度和高度:match_parent表示填满父组件,wrap_content表示组件实际大小
    android:layout_height="match_parent"
    android:orientation="vertical"		//orientation表示布局方向:vertical表示该组件中的子组件会一行一行排列,horizontal表示子组件一列一列的排列
    android:divider="@color/black"		//divider表示该组件中子组件之间的分割线:可以设置图片或颜色
    android:showDividers="middle"		//showDividers设置分割线的位置:分别为不显示none,开始处显示beginning,结尾处显示end,两个组件之间显示middle
	android:layout_weight="1"			//layout_weight设置该控件在父控件中所占的比例大小,用数字表示,可用于子控件
	android:background=""				//background设置该控件的背景颜色,可用于子控件	
	android:dividerPadding="10dp">			//设置分割线与组件两边的边距

2.相对布局

<RelativeLayout
	android:gravity="center"				//gravity用于设置该组件中子组件的对其方式
	android:ignoreGravity="@color/black">	//设置该组件中不受gravity影响的组件

除了上述两个属性外,RelativeLayout还有非常详细的子组件定位属性,大致分为以下四类:

a.根据父容器定位属性

右对齐
android:layout_alignParentRight="true"
左对齐
android:layout_alignParentLeft="true"
底部对齐
android:layout_alignParentBottom="true"
顶部对齐
android:layout_alignParentTop="true"
水平居中
android:layout_centerHorizontal="true"
垂直居中
android:layout_centerVertical="true"
中间位置
android:layout_centerInParent="true"

b.根据兄弟组件定位属性

参考兄弟组件的左边
android:layout_toLeftOf="@+id/兄弟组件的id"
参考兄弟组件的右边
android:layout_toRightOf="@+id/aaa"
参考兄弟组件的上方
android:layout_above="@+id/aaa"
参考兄弟组件的下方
android:layout_below="@+id/aaa"
参考兄弟组件的起始位置
android:layout_toStartOf="@+id/aaa"
参考兄弟组件的结束位置
android:layout_toEndOf="@+id/aaa"
对齐参考组件的上边界
android:layout_alignTop="@+id/aaa"
对齐参考组件的下边界
android:layout_alignBottom="@+id/aaa"  
对齐参考组件的左边界
android:layout_alignLeft="@+id/aaa"
对齐参考组件的右边界
android:layout_alignRight="@+id/aaa"

c.偏移属性(设置两个组件之间的边距)

设置组件四个方向的偏移距离
android:layout_margin="5dp"
设置组件离左边的偏离距离
android:layout_marginLeft="5dp"
设置组件离右边的偏离距离
android:layout_marginRight="5dp"
设置组件离上边的偏离距离
android:layout_marginTop="5dp"
设置组件离下边的偏离距离
android:layout_marginBottom="5dp"

d.填充属性(设置组件内部元素之间的边距)

往内部元素上下左右四个方向有填充一定边距
android:padding="5dp"
往内部元素的左边填充一定边距
android:paddingLeft="5dp"
往内部元素的右边填充一定边距
android:paddingRight="5dp"
往内部元素的上边填充一定边距
android:paddingTop="5dp"
往内部元素的下边填充一定边距
android:paddingBottom="5dp"
下面两个还没用过,先写上
android:paddingHorizontal="5dp"
android:paddingVertical="5dp"

举例说明:
在以下代码中,两个TextView都是RelativeLayout的子组件,两个TextView的关系是兄弟组件。
id为aaa的TextView没有设置其他属性,所以它的位置默认在界面的左上角。
id为bbb的TextView设置了layout_toRightOf属性,所有它在aaa的右边,然后还设置了layout_alignParentBottom属性,所以它靠近父组件的底部,layout_marginTop属性让他从底部网上偏移了5dp的举例,android:paddingLeft属性让它的文本内容左边有5dp的空白
所以效果如下图:
在这里插入图片描述

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/aaa"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
    
    <TextView
    	android:id="@+id/bbb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
       android:text="测试测试测试测试"
        android:layout_toRightOf="@+id/aaa"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="30dp"
        android:paddingLeft="60dp"
       />
</RelativeLayout>

3.表格布局:主要用于数据表显示

<TableLayout
	android:stretchColumns="0,4" >	//stretchColumns表示隐藏列,后面的数字表示第一列和第五列将被隐藏
	
	<TableRow>	//一个TableRow表示一行,如果一行中有多个组件则全部放在TableRow中
		<TextView />
	</TableRow> 
	
	<TableRow>
		<TextView />
	</TableRow>

</TableLayout>

4.帧布局:用于前景显示,设置跳转页面也不会被覆盖的内容

<FrameLayout
    android:foreground="@drawable/ic_launcher_background"	//foreground设置前景显示内容
    android:foregroundGravity="right" >           			//设置前景显示位置
</FrameLayout>

5.网格布局

<GridLayout
	android:layout_gravity="center"			//设置对其方式
	android:orientation="horizontal"		//设置排列方式
	android:columnCount="4"					//设置列数
	android:rowCount="6">					//设置行数
		<TextView
			android:layout_row="0"				//设置组件位于网格的第几行,从0开始
			android:layout_column="0"			//设置组件位于网格的第几列
			android:layout_rowSpan="0"			//设置组件横跨几行
			android:layout_columnSpan="4"	 />	//设置组件横跨几列
			
</GridLayout>

6.绝对布局

四大属性(单位:dp):高度,宽度,坐标x,坐标y
控制大小: android:layout_width:组件宽度 android:layout_height:组件高度
控制位置: android:layout_x:设置组件的X坐标 android:layout_y:设置组件的Y坐标

7.普通控件

文本框:

	<TextView
		android:id="@+id/tex"							//Java文件根据控件ID来操作控件
        android:layout_width="match_parent"				//layout_width和layout_height设置控件高度和宽度,根据父容器设置具体属性值
        android:layout_height="match_parent"
		android:background="@color/teal_700"/>			//background设置控件背景颜色,可以为图片
		
		//文本属性
        android:text=" 设置:"							//text设置文本内容,可用@string/id代替,从strings.xml文件中根据id值获取文本内容
        android:gravity="center_vertical"				//gravity设置文本对齐方式	
        android:textColor="@color/black"				//textColor设置文本颜色
        android:textStyle="bold"						//textStyle设置文本字体风格**normal**(无效果),**bold**(加粗),**italic**(斜体)
        android:textSize="20sp"							//textSize设置字体大小,单位sp
        			
		//阴影属性
		android:shadowColor:设置阴影颜色,需要与shadowRadius一起使用
		android:shadowRadius:设置阴影的模糊程度,设为0.1就变成字体颜色了,建议使用3.0
		android:shadowDx:设置阴影在水平方向的偏移,就是水平方向阴影开始的横坐标位置
		android:shadowDy:设置阴影在竖直方向的偏移,就是竖直方向阴影开始的纵坐标位置
		
	修改文本框内容:先实例化,然后赋值
	TextView tex = (TextView) findViewById(R.id.tex);
	R.string.teaa是调用strings.xml文件中的字符串,teaa为字符串name
	tex.setText(R.string.teaa)
	tex.setText(“amdlkgma”)		//直接赋值	

输入框:

	<EditText
		//默认提示文本
		android:hint="默认提示文本"			//文本内容
		android:textColorHint="#95A1AA"		//文本颜色
		
		android:selectAllOnFocus="true"		//点击输入框,全选输入框中的文本内容
		
		android:inputType="phone"			//限制输入的内容
		常用属性值有:
			number :数字	phone:拨号键盘		textPassword:密码		date:日期键盘  time:时间键盘
		
		//控制文本行数
		android:minLines="3"		//输入文本最小行数
		android:maxLines="3"		//最大行数
		android:singleLine="true"	//单行
		
		//控制文本间隔
		android:textScaleX="1.5"    //设置字与字的水平间隔
		android:textScaleY="1.5"    //设置字与字的垂直间隔
		
		//设置英文字母大写类型
		android:capitalize="sentences"	//sentences:仅第一个字母大写;words:每一个单词首字母大小,用空格区分单词;characters:每一个英文字母都大写;默认none
		
		//边距控制
		android:marginTop = "5dp"		//margin属性设置输入框与其他控件的边距
		android:paddingTop = "5dp"		//padding属性设置文本与输入框的边距
		
	//输入框操作:
		在AndroidManifest.xml文件中本页面activity中添加android:windowSoftInputMode="stateHidden|adjustPan",stateHidden表示隐藏软键盘,adjustPan表示控件不会因为输入法的弹出而发生形变  
	
		<activity android:name=".MainActivity" android:windowSoftInputMode="stateHidden|adjustPan">
	
	获取输入框内容
	首先实例化输入框:
	EditText edt = (EditText)findViewById(R.id.editText);
	获取:
	String edtt = edt.getText().toString();


	清空输入框内容
	edt.setText("");
    edt.requestFocusFromTouch();

按钮Button和ImageButton

	drawable:引用的Drawable位图,我们可以把他放到最前面,就表示组件的正常状态~
	state_focused:是否获得焦点
	state_window_focused:是否获得窗口焦点
	state_enabled:控件是否可用
	state_checkable:控件可否被勾选,eg:checkbox
	state_checked:控件是否被勾选
	state_selected:控件是否被选择,针对有滚轮的情况
	state_pressed:控件是否被按下
	state_active:控件是否处于活动状态,eg:slidingTab
	state_single:控件包含多个子控件时,确定是否只显示一个子控件
	state_first:控件包含多个子控件时,确定第一个子控件是否处于显示状态
	state_middle:控件包含多个子控件时,确定中间一个子控件是否处于显示状态
	state_last:控件包含多个子控件时,确定最后一个子控件是否处于显示状态
	
	
	按钮监听事件
	在onCreate()方法中实例化按钮添加以下代码
	Button bus = (Button)findViewById(R.id.bus);
	bus.setOnClickListener(new bbb());
	新建bbb()方法实现监听事件
		class bbb implements View.OnClickListener{
			@Override
			public void onClick(View view) {				
				监听到点击该按钮时执行的代码
			}
		}

图像控件ImageView

	android:src="@drawable/pen" 			//src设置图片路径,图片会按原本大小显示
	android:background="@drawable/pen"		//background设置图片路径,图片被放大或缩小占满控件

单选框

<RadioGroup
    android:id="@+id/radioGroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">		//orientation设置组件为横向排列还是纵向排列

    <RadioButton
        android:id="@+id/btnMan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="男"
        android:checked="true"/>			//checked设置默认值,true表示默认选择,false表示默认不选

    <RadioButton
        android:id="@+id/btnWoman"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="女"/>
</RadioGroup>

	//获取单选值
	在onCreate()方法中实例化按钮添加以下代码
	RadioGroup radgroup = (RadioGroup) findViewById(R.id.radioGroup);
	radgroup.setOnCheckedChangeListener(new eckedChangeListener());
	新建eckedChangeListener()方法实现监听事件
		class eckedChangeListener implements RadioGroup.OnCheckedChangeListener {

		@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				RadioButton radbtn = (RadioButton) findViewById(checkedId);
				boolean aaa = radbtn.isChecked();		//判断按钮是否选中
				
				Toast.makeText(getApplicationContext(), "按钮组值发生改变,你选了" + radbtn.getText(), Toast.LENGTH_LONG).show();
			}
		};

复选框:每个CheckBox都要设置一个id

	 <CheckBox
            android:id="@+id/chb1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="苹果">
        </CheckBox>

        <CheckBox
            android:id="@+id/chb2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="雪梨">
        </CheckBox>

        <CheckBox
            android:id="@+id/chb3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="可乐">
        </CheckBox>
		
		<Button
            android:id="@+id/buttnos"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="@string/but" />

	获取复选框的值
		CheckBox cb_one = (CheckBox) findViewById(R.id.chb1);
        CheckBox cb_two = (CheckBox) findViewById(R.id.chb2);
        CheckBox cb_three = (CheckBox) findViewById(R.id.chb3);

开关按钮和图标

	<ToggleButton				//按钮开关
            android:id="@+id/tbtn_open"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textOff="已打开"
            android:textOn="已关闭" />

        <Switch					//左右滑动的开关
            android:id="@+id/swh_status"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:showText="true"				//设置是否显示文字
            android:textOff="1"					//设置关闭时显示的文字
            android:textOn="2"					//设置打开时显示的文字

进度条

	<ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"		style设置进度条的样式
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"				//设置进度条的最大值
        android:progress="75" />		//设置当前进度值
	
	常用方法:
	getMax():返回这个进度条的范围的上限
	getProgress():返回进度

拖动条

	<SeekBar
            android:id="@+id/sb_normal"		             
            android:max="100"				//设置滑动最大值
            android:progress="80"			//设置默认值
     />
	
	用法:
		在onCreate中实例化拖动条,设置监听事件setOnSeekBarChangeListener
			SeekBar skb = (SeekBar)findViewById(R.id.sb_normal);
			skb.setOnSeekBarChangeListener(new setonsjb());
		重写OnSeekBarChangeListener中的三个方法:
		class setonsjb implements SeekBar.OnSeekBarChangeListener{
			TextView tex = (TextView) findViewById(R.id.notex);
			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {	//onProgressChanged进度改变时触发该方法,获取进度值显示出来
				tex.setText("进度:" + progress);
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {			//触碰进度条时触发
				Toast.makeText(MainActivity.this, "触碰SeekBar", Toast.LENGTH_SHORT).show();		
			}

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {			//放开进度条时触发
				Toast.makeText(MainActivity.this, "放开SeekBar", Toast.LENGTH_SHORT).show();
			}
		}

时间控件

	文本时钟
	 <TextClock
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
	
	模拟时钟
	 <AnalogClock
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
             />

三、apk全局参数的应用

直接上代码
MainActivity.java

public class MainActivity extends AppCompatActivity {
    	//全局参数必须设置为public static
    	public static String name = "name";
    	TextView bt;
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
        	super.onCreate(savedInstanceState);
        	setContentView(R.layout.activity_main);
        	bt = (TextView) findViewById(R.id.bt);
        	bt.setOnClickListener(new View.OnClickListener() {
            	@Override
            	public void onClick(View v) {
                	Intent it = new Intent(MainActivity.this, MainActivity2.class);
                	startActivity(it);
            	}
        	});
    	}
}

MainActivity2.java

public class MainActivity2 extends AppCompatActivity {
    	String name;

    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
        	super.onCreate(savedInstanceState);
        	setContentView(R.layout.activity_main2);
        	name = MainActivity.name;
        	Toast.makeText(MainActivity2.this, name, Toast.LENGTH_SHORT).show();
    	}
}

四、Activity数据持久化

onCreate()方法带一个参数

public class MainActivity extends AppCompatActivity {

//   1.点击home键回到主页或长按后选择运行其他程序
//    2.按下电源键关闭屏幕
//    3.启动新的Activity
//    4.横竖屏切换时使用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //判断是否有保存的数据,如果有则直接使用
        if (savedInstanceState != null) {
            Log.d("onCreate()", savedInstanceState.getString("octopus"));
        }
    }

    //横竖屏切换后调用恢复数据,也可以再ocreate中恢复
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d("onRes", savedInstanceState.getString("octopus"));

    }

    //横竖屏切换时调用保存数据
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("octopus", "www.baidu.com");
        Log.d("onSave()", "save date www.baidu.com");

    }

}

onCreate()方法带两个参数

public class MainActivity extends AppCompatActivity {
    /*
         activity持久化:
         1.再manifest配置文件的activity中添加代码android:persistableMode="persistAcrossReboots"
         2.重写onCreate方法,带两个参数
         3.搭配以下两个方法

         onCreate(Bundle):当Activity非正常销毁之后,例如手机旋转,内存不足导致的后台自动销毁。
         onCreate(Bundle, PersistableBundle):手机由于过热,没电或者第三方定制Rom由于卡顿而异常关机的情况,能找回之前前台的数据,实际上是一种数据持久化的Activity。
     */
    @Override
    public void onCreate(Bundle savedInstanceState, PersistableBundle persistableBundle) {
        super.onCreate(savedInstanceState, persistableBundle);
        setContentView(R.layout.activity_main);
        Log.d("调用", "onCreate()");

    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

    @Override
    public void onRestoreInstanceState(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
        super.onRestoreInstanceState(savedInstanceState, persistentState);
    }

}

五、Activity之间的数据传递

传递一个数据

传递:
Intent d = new Intent(MainActivity.this, MainActivity2.class);
d.putExtra("d", "传递一个简单数据");         //第一个参数为传递的数据名称,第二个参数为具体数据
startActivity(d);

接收:
Intent it = getIntent();
String date = it.getStringExtra("d");

传递多个数据传递:

传递:
Intent i = new Intent(MainActivity.this, MainActivity3.class);
Bundle bl = new Bundle();
bl.putString("a", "第一个数据");
bl.putString("b", "第二个数据");
i.putExtras(bl);
startActivity(i);

接收:
Intent it = getIntent();
String date = it.getStringExtra("a");
String date2 = it.getStringExtra("b");

传递数组传递:

传递:
Intent e = new Intent(MainActivity.this, MainActivity4.class);
Bundle ba = new Bundle();
ba.putStringArray("e", new String[]{"数组中第一个数", "数组中第二个数"});
e.putExtras(ba);
startActivity(e);

接收:
Intent it = getIntent();
String[] str = it.getStringArrayExtra("e");

传递集合

传递:
Intent f = new Intent(MainActivity.this, MainActivity5.class);
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
f.putStringArrayListExtra("f", sites);
startActivity(f);

接收:
Intent it = getIntent();
ArrayList<String> sites = it.getStringArrayListExtra("f");

多个Activity间的交互(后一个传回给前一个)

MainActivity.java

public class MainActivity extends AppCompatActivity {
    Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("MainActivity", "onCreate()");
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent a = new Intent(MainActivity.this, MainActivity2.class);
                startActivityForResult(a, 123);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 123 && resultCode == 456) {
            Bundle bd = data.getExtras();
            String a = bd.getString("a");
            Toast.makeText(MainActivity.this, a, Toast.LENGTH_SHORT).show();

        }
    }
}

MainActivity2.java

public class MainActivity2 extends AppCompatActivity {
    Button bt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Log.d("MainActivity2", "onCreate()");
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent it = getIntent();
                Bundle bd = new Bundle();
                bd.putString("a", "AAAAAAA");
                it.putExtras(bd);
                setResult(456, it);
                finish();
            }
        });
    }
}

六、activity启动时根据横竖屏状态加载不同的布局

public class MainActivity extends AppCompatActivity {

    /*
       操作步骤:
       1.创建横竖屏不同的布局文件,文件名称要相同,创建方法见附图:选中layout文件夹右键new-layout Resource File
       2.onCreate()方法中添加横竖屏判断加载布局
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.activity_main);
        } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            setContentView(R.layout.activity_main);
        }
    }
}

在这里插入图片描述

六、隐式启动activity

隐式启动常用于不同应用之间的跳转(例如打开支付宝微信的支付页面),也可用于H5与native之间的交互。隐式启动就是action,category和data的匹配
1.在要启动的activity中添加以下代码

<intent-filter>
             <action android:name="my_action"/>
             <category android:name="my_category"/>
             <category android:name="android.intent.category.DEFAULT"/>
 </intent-filter>

2.创建页面跳转Intent,参数为my_action

action匹配规则:
1.action在Intent-filter可以设置多条
2.intent中必须指定action否则匹配失败且intent中action最多只有一条
3.intent中的action和intent-filter中的action必须完全一样时(包括大小写)才算匹配成功
4.intent中的action只要与intent-filter其中的一条匹配成功即可

category匹配规则:
1.category用于指定当前动作(action)执行的环境,即这个activity在哪个环境中才能被激活。不属于这个环境的,不能被激活
2.如果目标activity想要通过隐式调用方式激活,那么不能没有任何category设置,至少包含一个android.intent.category.DEFAULT
3.一个intent只能有一个action,但是可以有多个category。同一个intent中多个category彼此间是“与”的关系,也就是说一个组件要支持全部的category才能处理该请求。

AndroidManifest.xml

 <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LmplicitStart">

        <activity android:name=".MainActivity2">
            <intent-filter>
                <action android:name="my_action" />
                <category android:name="my_category"/>
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 </application>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    Button bt;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.bt);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent a = new Intent();
                //action和category二选一即可
                a.setAction("my_action");
                a.addCategory("my_category");

                startActivity(a);
            }
        });
    }
}

七、双击退出APP

第一种方法:定义一个变量,来标识是否退出

public class MainActivity extends AppCompatActivity {
    private static boolean isExit = false;
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            isExit = false;
        }
    };

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

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (!isExit) {
                isExit = true;
                Toast.makeText(getApplicationContext(), "再按一次退出程序",
                        Toast.LENGTH_SHORT).show();
                // 利用handler延迟发送更改状态信息
                mHandler.sendEmptyMessageDelayed(0, 2000);
            } else {
                AppExit();
            }
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }
    /**
     * 完全退出应用程序,包括后台任务
     * 需添加权限:android.permission.KILL_BACKGROUND_PROCESSES
     */
    public void AppExit() {
        try {
            finish();
            ActivityManager activityMgr = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(this.getPackageName());
            System.exit(0);
        } catch (Exception ignored) {
        }
    }
 }

第二种方法:保存点击时间

public class MainActivity extends AppCompatActivity {
    private long exitTime = 0;

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

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                AppExit();
            }
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }
    
    public void AppExit() {
        try {
            finish();
            ActivityManager activityMgr = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(this.getPackageName());
            System.exit(0);
        } catch (Exception ignored) {
        }
    }
}

八、Activity过场动画

首先添加创建过场动画资源
在res目录下创建anim文件夹,然后将动画资源拖进去
在这里插入图片描述

为单个Activity设置进入和退出的过场动画

在Activity启动或者退出时加上这一行代码即可:
overridePendingTransition(R.anim.hyperspace_in, R.anim.hyperspace_out);

bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this,MainActivity2.class));
                //页面跳转时添加
                overridePendingTransition(R.anim.hyperspace_in, R.anim.hyperspace_out);
            }
        });
  	@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
           finish();
           //退出时添加
            overridePendingTransition(R.anim.push_up_in, R.anim.push_up_out);
        }
        return super.onKeyDown(keyCode, event);
    }

为所有Activity设置进入和退出的过场动画

直接在themes.xml文件中添加以下代码。
添加时要查看APP的style中有没有

<item 	name="android:windowAnimationStyle">@style/default_animation</item>

没有的话要手动添加上

 <style name="default_animation" mce_bogus="1" parent="@android:style/Animation.Activity">
        <item name="android:activityOpenEnterAnimation">@anim/push_left_in</item>
        <item name="android:activityOpenExitAnimation">@anim/push_up_in</item>
        <item name="android:activityCloseEnterAnimation">@anim/push_up_out</item>
        <item name="android:activityCloseExitAnimation">@anim/push_left_out</item>
 </style>

九、设置Activity全屏的四种方法

1.在onCreate方法中添加一行代码去掉

getSupportActionBar().hide();

2.在themes.xml文件中将style的parrent改为

parent="Theme.AppCompat.Light.NoActionBar

3.在themes.xml文件中的style里面添加以下item

<item name="windowNoTitle">true</item>

4.在把 super.onCreate(savedInstanceState);前面添加以下代码

requestWindowFeature(Window.FEATURE_NO_TITLE);

十、设置对话框风格Activity的两种方法

1.直接引用对话框风格的theme
在AndroidManifest.xml中注册的Activity中添加
android:theme=“@style/Theme.AppCompat.Light.Dialog”

 <activity
            android:name=".MainActivity5"
            android:theme="@style/Theme.AppCompat.Light.Dialog" />
 <activity android:name=".MainActivity4" />

2.在themes.xml文件中自定义一个style,然后在Activity中引用

  <style name="dialog_style" parent="Theme.ActivityOther">
        <!--是否悬浮在activity上-->
        <item name="android:windowIsFloating">true</item>
        <!-- 设置是否透明 -->
        <item name="android:windowIsTranslucent">true</item>
        <!-- 背景 -->
        <item name="android:background">@null</item>
        <!--设置没有窗口标题、dialog标题等各种标题-->
        <!-- 无标题 -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:title">@null</item>
        <item name="android:dialogTitle">@null</item>

        <!-- 去黑边 -->
        <item name="android:windowFrame">@null</item>
        <!-- 窗口背景 -->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!-- 是否变暗 -->
        <item name="android:backgroundDimEnabled">false</item>
        <!-- 点击空白部分activity不消失 -->
        <item name="android:windowCloseOnTouchOutside">false</item>
        
    </style>

十、onWindowFocusChanged方法的应用

回调时机:当Activity得到或者失去焦点的时候回调,
作用:
1.监控Activity是否加载完毕
2.测量控件,获取控件的宽高
3.设置控件进入时的默认值
参数解析:
hasFocus:进入或恢复Actiity时为true,Actvity销毁或者退到后台则为false

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            Log.d("MainActivity4", "Activity加载完毕!");
            int[] a = new int[2];
            bt.getLocationOnScreen(a);
            int x = a[0];
            int y = a[1];
            int m = bt.getHeight();     //横屏为宽度,竖屏为高度
            int n = bt.getWidth();
            Log.d("参数为", x + "," + y + "," + m + "," + n);
            Log.d("左上角坐标为", x + "," + y);
            Log.d("右上角坐标为", (x + n) + "," + y);
            Log.d("左下角坐标为", x + "," + (y + m));
            Log.d("右上角坐标为", (x + n) + "," + (y + m));
        }
    }

十一、Activity管理类的使用以及关闭所有acitivity和完全退出app的方法

首先创建一个Activity管理类:
activity管理类解析:
1.创建一个全局变量list
2.创建三个方法:
a.将activity添加到list中
b.在list中删除单个activity
c.关闭list中的所有activity
activity管理类使用:
1.activity启动时在onCreate方法中将activity添加到list中
2.activity关闭时在onDestroy方法中将activity从list中删除
3.退出应用时调用finishAll方法将list中的所有activity关闭

ActivityCollector.java

public class ActivityCollector {
 
    public static LinkedList<Activity> activities = new LinkedList<Activity>();

    //添加activity
    public static void addActivity(Activity activity) {
        activities.add(activity);
    }

    //删除activity
    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }

    //关闭所有activity
    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
    }
}

在Activity加载完成后调用管理类中添加activity的方法

ActivityCollector.addActivity(this);

在Activity退出时调用管理类中删除activity的方法

ActivityCollector.removeActivity(this);

在整个APP退出时调用管理类中关闭所有activity的方法

  /**
     * 完全退出应用程序,包括后台任务
     * 需添加权限:android.permission.KILL_BACKGROUND_PROCESSES
     */
    public void AppExit(Context context) {
        try {
            ActivityCollector.finishAll();
            ActivityManager activityMgr = (ActivityManager) context
                    .getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.killBackgroundProcesses(context.getPackageName());
            System.exit(0);
        } catch (Exception ignored) {
        }
    }

十二、设计堆栈的Activity管理类

开源中国客户端Activity管理类

public class AppManager {

    private static Stack<Activity> activityStack;
    private static AppManager instance;

    private AppManager(){}
    /**
     * 单一实例
     */
    public static AppManager getAppManager(){
        if(instance==null){
            instance=new AppManager();
        }
        return instance;
    }
    /**
     * 添加Activity到堆栈
     */
    public void addActivity(Activity activity){
        if(activityStack==null){
            activityStack=new Stack<Activity>();
        }
        activityStack.add(activity);
    }
    /**
     * 获取当前Activity(堆栈中最后一个压入的)
     */
    public Activity currentActivity(){
        Activity activity=activityStack.lastElement();
        return activity;
    }
    /**
     * 结束当前Activity(堆栈中最后一个压入的)
     */
    public void finishActivity(){
        Activity activity=activityStack.lastElement();
        finishActivity(activity);
    }
    /**
     * 结束指定的Activity
     */
    public void finishActivity(Activity activity){
        if(activity!=null){
            activityStack.remove(activity);
            activity.finish();
            activity=null;
        }
    }
    /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls){
        for (Activity activity : activityStack) {
            if(activity.getClass().equals(cls) ){
                finishActivity(activity);
            }
        }
    }
    /**
     * 结束所有Activity
     */
    public void finishAllActivity(){
        for (int i = 0, size = activityStack.size(); i < size; i++){
            if (null != activityStack.get(i)){
                activityStack.get(i).finish();
            }
        }
        activityStack.clear();
    }
    /**
     * 退出应用程序
     */
    public void AppExit(Context context) {
        try {
            finishAllActivity();
            ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            activityMgr.restartPackage(context.getPackageName());
            System.exit(0);
        } catch (Exception e) {    }
    }
}


总结

关于控件部分,因为常用控件太多,还有一部分常用控件未作说明,以后单独写一篇