Activity
每一个界面都需要一个activity,activity不等于界面
一个activity可以包含很多fragment,fragment需要依赖于activity
Activity的创建步骤
1 新建activity类继承Activity
2 在androidManifest中声明
3创建layout文件并在activity中的Oncreate中进行绑定
在清单文件中设置标题
android:label="这是标题"
设置主题(当前为没有顶部栏)要设置全局的话在application内进行设置
android:theme="@style/Theme.AppCompat.Light.NoActionBar"
设置竖屏显示默认的是横过来横屏显示,竖过来竖屏显示
android:screenOrientation="portrait"
启动模式
android:launchMode=""
生命周期流程图
activity的生命周期
package com.tz.tian;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class LifeCycleActivity extends AppCompatActivity {
//刚进入activity的时候经过三个方法,依次是onCreate,onStart,onResume
//返回的时候经过三个方法,依次是onPause,onStop,onDestroy
//常用的onCreate设置布局文件,onResume,每次进入都希望做的操作,比如数据的刷新,onPause程序在后台
//onDestroy在页面结束之前
//程序到后台时会运行onPause,onStop
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Log.d("Lifecycle","onStart");
}
@Override
protected void onStart() {
super.onStart();
Log.d("Lifecycle","onStart");
}
@Override
protected void onResume() {
super.onResume();
}
@Override
//如果程序到了后台运行,也会执行这个函数
protected void onPause() {
super.onPause();
Log.d("Lifecycle","onstart");
}
@Override
protected void onStop() {
super.onStop();
Log.d("Lifecycle","onStop");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("Lifecycle","onRestart");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Lifecycle","onDestroy");
}
}
Activity的跳转和数据传递
package com.tz.tian.jump;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.tz.tian.R;
public class AActivity extends AppCompatActivity {
private Button mBtnJump;
protected void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
mBtnJump=findViewById(R.id.jump);
mBtnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//显式跳转这种最为广泛
//Intent intent=new Intent(AActivity.this,BActivity.class);
//startActivity(intent);
//显式2
//Intent intent=new Intent();
//intent.setClass(AActivity.this,BActivity.class);
//startActivity(intent);
//显式3
//Intent intent=new Intent();
//intent.setClassName(AActivity.this,"com.tz.tian.jump.BActivity");
//startActivity(intent);
//隐式调用
Intent intent=new Intent();
intent.setAction("com.skypan.test.BActivity");
startActivity(intent);
}
});
}
}
androidMainfest.xml
<activity android:name=".jump.BActivity" android:label="B">
<intent-filter>
<action android:name="com.skypan.test.BActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Activity之间的数据传递
AActivity.java
package com.tz.tian.jump;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.tz.tian.R;
public class AActivity extends AppCompatActivity {
private Button mBtnJump;
protected void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
mBtnJump=findViewById(R.id.jump);
mBtnJump.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//显式跳转这种最为广泛
Intent intent=new Intent(AActivity.this,BActivity.class);
//数据传递是通过bundle,把一个bundle放到一个intent里面
Bundle bundle=new Bundle();
bundle.putString("name","天哥");//把数据放到bundle中
bundle.putInt("number",88);
intent.putExtras(bundle);//把bundle放到intent之中
/*
在开发项目过程中,startActivityForResult是最常见的,它的使用场景就是:
比如从AActivity跳转到BActivity,然后在BActivity中做一系列操作
,然后在BActivity关闭时候需要把一些数据再回传给AActivity,或
者当BActivity关闭后,需要让AActivity的界面或者数据发生一些变化,
这个时候就需要用到 startActivityForResult。
*/
//参数intent,参数2.requescode,你自定义的一个int类型的数值(一般>0),
// 当从activityB中返回来的时候。会携带回来。所以你可以用这个参数来判断是从哪个activity中返回的
startActivityForResult(intent,0);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
//第一个参数回调过来的requestcode(请求码0),第二个参数和第三个参数都是传递过来的
super.onActivityResult(requestCode, resultCode, data);
String title = data.getExtras().getString("title");//获取传递过来的数据
Toast.makeText(AActivity.this,title,Toast.LENGTH_LONG).show();
}
}
BACtivity.java
package com.tz.tian.jump;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.tz.tian.R;
public class BActivity extends AppCompatActivity {
private TextView mTvtTitle;
private Button mBtnFinish;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
mTvtTitle=findViewById(R.id.tv_title);
mBtnFinish=findViewById(R.id.btn_finish);
//接收传过来的bundle
final Bundle bundle = getIntent().getExtras();
//通过bundle获取数据
String name = bundle.getString("name");
int number = bundle.getInt("number");
mTvtTitle.setText(name+""+number);
mBtnFinish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent();
Bundle bundle1=new Bundle();
bundle1.putString("title","我回来了");
intent.putExtras(bundle1);
/*
* 在意图跳转的目的地界面调用这个方法把Activity想要返回的数据返回到主Activity,
第一个参数:当Activity结束时resultCode将归还在onActivityResult()中,
一般为RESULT_CANCELED , RESULT_OK该值默认为-1。
第二个参数:一个Intent对象,返回给主Activity的数据。
在intent对象携带了要返回的数据,使用putExtra( )方法。上面由济南大介绍。
* */
setResult(Activity.RESULT_OK,intent);
//关闭当前页面
finish();
}
});
}
}
Activity的四种启动模式
activityd的Android:launchMode属性
standard:标准模式也是默认的模式 //常用
singleTop:Task栈顶复用模式 //常用
singleTask:Task栈内复用模式 //常用
singleInstance:全局单例模式,只要存在目标Activity就复用 //少用
Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity
standard
是默认的启动模式, 即标准模式。每启动一个Activity,都会创建一个新的实例
SingileTask
在同一个任务栈中,如果要启动的目标Activity已在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且在该Activity上面的Activity会被清除,如果栈中没有,则创建新的Activity
SingleTop
当要启动的目标已经位于栈顶时,不会创建新的实例会复用栈顶的Activity,并且其onNewIntent()方法会被调用,如果目标Activity不存在栈顶,则跟standard一样创建新的实例
singleInstance
全局复用,不管哪个task栈,只要存在目标Activity就复用,每个Activity占有一个新的Task栈,只要手机里面有这个Activity就复用(除了和别的app联动以外一般用不到)
Fragment
- Fragment是依赖于Activity的,不能独立存在的。
- 一个Activity里可以有多个Fragment。
- 一个Fragment可以被多个Activity重用。
- Fragment有自己的生命周期,并能接收输入事件。
- 我们能在Activity运行时动态地添加或删除Fragment。
- Fragment通过getActivity()可以获取坐在的Activity;Activity通过FramentManager的findFragmentById()或findFragment()获取Fragment
- Fragment和Activity是多对多的关系
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#000"
android:textSize="20sp"
android:text="我是AFragment"
android:gravity="center"
/>
</LinearLayout>
AFragment.java
package com.tz.tian.fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTabHost;
import com.tz.tian.R;
public class AFragment extends Fragment {
private TextView mTvTitle;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTvTitle=view.findViewById(R.id.tv_title);
}
}
fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:textColor="#000"
android:textSize="20sp"
android:text="我是BFragment"
android:gravity="center"
/>
</LinearLayout>
fragment_b.java
package com.tz.tian.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.tz.tian.R;
public class BFragment extends Fragment {
private TextView mTvTitle;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTvTitle=view.findViewById(R.id.tv_title);
}
}
activity_container.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.ContainerActivity">
<Button
android:id="@+id/btn_change"
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="更换Fragment"
/>
<FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/btn_change"
></FrameLayout>
</RelativeLayout>
ContaninerActivity.java
package com.tz.tian.fragment;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.tz.tian.R;
public class ContainerActivity extends AppCompatActivity {
private AFragment aFragment;
private BFragment bFragment;
private Button mBtnChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
mBtnChange=findViewById(R.id.btn_change);
mBtnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (bFragment==null)
bFragment =new BFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).commitAllowingStateLoss();
}
});
//实例化Afragment
aFragment=new AFragment();
//把aFragment添加到Activity中
getSupportFragmentManager().beginTransaction().add(R.id.fl_container,aFragment).commitAllowingStateLoss();
}
}
基于监听的事件处理机制
监听三要素
- 事件源
- 事件
- 事件监听器
以下例子是一个点击的监听器
//事件源是btn
//监听器是new View.OnclickListener
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
实现监听时间的方法
- 通过内部类实现、
- 通过匿名类实现
- 通过时间源所在类实现
- 通过外部类实现
- 布局文件中onClick属性(针对点击事件)
给同一个事件源,添加了多个点击事件的时候,系统响应的是最后一个设置的事件
activity_event.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".EventActivity">
<Button
android:id="@+id/btn_event"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="click me"
android:onClick="show"
/>
</LinearLayout>
EventActivity.java
package com.tz.tian;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.tz.tian.util.ToastUtil;
public class EventActivity extends AppCompatActivity implements View.OnClickListener {
private Button mBtnEvent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_event);
mBtnEvent=findViewById(R.id.btn_event);
//内部类实现
//mBtnEvent.setOnClickListener(new Onclick());
//匿名内部类
// mBtnEvent.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// ToastUtil.showMsg(EventActivity.this,"click");
// }
// });
//由于自己实现了OnClickListener所以直接调用自己即可
//mBtnEvent.setOnClickListener(EventActivity.this);
//通过外部类实现
mBtnEvent.setOnClickListener(new MyclickListener(EventActivity.this));
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_event:
ToastUtil.showMsg(EventActivity.this,"click");
break;
}
}
class Onclick implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_event:
ToastUtil.showMsg(EventActivity.this,"click");
break;
}
}
}
//通过界面设置点击事件绑定这里的函数,会把view给返回
public void show(View v){
switch (v.getId()){
case R.id.btn_event:
ToastUtil.showMsg(EventActivity.this,"click");
break;
}
}
}
MyclickListener.java
package com.tz.tian;
import android.app.Activity;
import android.view.View;
import com.tz.tian.util.ToastUtil;
public class MyclickListener implements View.OnClickListener{
private Activity mActivity;
public MyclickListener(Activity activity){
mActivity=activity;
}
@Override
public void onClick(View view) {
ToastUtil.showMsg(mActivity,"click---");
}
}
基于回调的事件处理机制
handler消息处理
- 未来某时做某事
- 线程之间的通信