安卓Android开发快速入门

安卓Android开发快速入门,第1张

文章目录 UI组件(控件)布局管理器LinearLayout(线性布局)relativelayout(相对布局) 使用控件的步骤设置点击事件步骤的优化 TextView应用场景 Button(TextView的子类)特有属性应用场景 EditText(TextView的子类)常用(特有)属性制作登录界面+监听事件(监听控件)在控制台监听输入用户名的信息 RadioButton(Button子类)常用(特有)属性RadioGroup属性自定义样式selector中的item标签中的属性 监听事件 复选框CheckBox常用属性item属性 监听事件 ImageView常用属性ImageVIew对象常用方法如何加载网络图片(使用第三方图片加载库glide)导入方法简单使用案例 列表视图ListView(过时,迷迷糊糊)自定义Activity自定义ListView常用属性自定义Adapter接口点击事件(长按或点击) 网格视图GridView(过时,与ListView相似)常用属性Adapter接口点击事件 滚动视图ScrollView垂直滚动:ScrollView水平滚动:HorizontalScrollView RecyclerView控件(跳了)LinearRecyclerViewActivity WebView控件加载网页加载URL(网络的html文件)如果没有加载出来,是因为默认不加载js代码,需要设置一下如果跳转到浏览器,没有在应用里打开网页需要设置一下当在网页内返回时直接退出activity需要重写一个方法 加载本地assets文件夹(放一些不需要编译的文件)加载html代码网页的前进后退按下返回键,默认是退出当前Activity,如果希望是VebView内页面后退 UI组件之d出组件Toast设置显示的位置自定义显示内容Toast对象常用方法/构造器简单封装,公具类 ToastUtil AlertDialog警示对话框AlertDialog.Builder 常用方法默认样式单选样式多选样式自定义样式(登录样式) ProgressBar&ProgressDialogProgressBar常用属性 ProgressDialogProgressDialog类的常用方法实例1实例2 自定义Dialog(?)设置dialog形状(shape) PopupWindowd出窗口常用方法实例 不可不会的Activity和FragmentActivity的创建三部曲Activity属性如何自定义一个页面标题栏 Activity的生命周期Activity的跳转和数据传递显式跳转和隐式跳转Activity之间的数据传递startActivity:启动Activity,结束后返回结果 Activity的4种启动方式standardsingleTopsingleTasksingleInstance Fragment常用属性方法Fragment中getActivity()为可能null的问题向Fragment传递参数Fragment回退栈Fragment和Activity的通信 必须深刻理解的Android事件处理基于监听的事件处理机制监听三要素实现监听事件的方法 基于回调的事件处理机制(跳)源码剖析,了解View的事件分发(跳)Handler消息处理常用方法 数据存储sharedpreference轻量数据储存Android储存概念File内部储存(安卓系统内置的存储)File外部存储(向sd卡读写) 广播LocalBroadcastManager()实例 属性动画ValueAnimatorObjectAnimator.ofFloat()
配合天哥视频食用更佳: 【天哥】Android开发视频教程最新版 Android Studio开发

UI组件(控件) 布局管理器 LinearLayout(线性布局)

可嵌套

最常用属性

id 起标记布局的作用

layout_width [wrap_content根据内容选择大小、match_parent匹配父级、具体数值(单位-dp)]

layout_height

layout_weight 权重,按照权重比例分配父级剩余的空间。当把两个子元素水平排列,并且每个子元素的宽度设为0dp,权重都设为1,两个子元素将会平分父级宽度,各占一半

background

layout_margin 外边距

layout_padding 内边距

orientation 设置线性布局的方向

gravity 设置内部元素对齐方式

relativelayout(相对布局)

layout_toLeftOf 设置在xx的左边

layout_toRightOf 设置在xx的右边

layout_alignBottom 设置在xx的最底部

layout_alignParentBottom 设置自己在父级元素的底部

layout_below 设置在xx的下面

使用控件的步骤

在MainActivity里声明控件(启动页activity的设置方法,需要在目标activity添加intent-filter标签

<activity android:name=".MainActivity">
	<intent-filter>
		<action android:name="android.intent.action.MAIN"/>
		<category android:name="android.intent.category.LAUNCHER"/
	</intent-filter>
</activity>

找到控件

类型转换

设置点击事件

(

创建目标activity在Androidmanifest.xml声明这个activity在目标activity进行设计

)

private Button mBtn3;//1.在MainActivity里声明控件
@Override
protected void onCreate(Bundle savedInstancestate){
	super.onCreate(savedInstancestate);
	setContentview(R.layout.activity_button);
	mBtn3 = (Button)findviewById(R.id.btn_3);//2.找到控件 3.类型转换
	mBtn3.setonclickListener(new View.OnclickListener(){//设置点击事件
		@Override
		public void onclick(View v){
			Toast.makeText(ButtonActivity.this,"btn3被点击了"Toast.LENGTH_SHORT).show();
});
设置点击事件步骤的优化 自定义OnClick类,该类实现View.OnClickListener接口在OnClick类里重写onClick方法,参数是View类型onClick方法需要声明一个Intent对象,然后通过switch判断传入View对象的id,不同的id对应不同的Intent对象在主类里声明方法setListeners,在里边new一个自定义类OnClick的对象,把这个对象分别放在每个按钮的setOnClickListener方法里在Oncreat方法里找到每个按钮的对象,最终调用一次setListeners方法
public class MainActivity extends AppCompatActivity {

    private Button mBtnUI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnUI = (Button) findViewById(R.id.btn_ui);
        OnClick onClick = new OnClick();
        mBtnUI.setOnClickListener(onClick);
    }

    class OnClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent = null;
            switch (v.getId()){
                case R.id.btn_ui:
                    intent = new Intent(MainActivity.this,UIActivity.class);
                    break;
            }
            startActivity(intent);
        }
    }
}
TextView 应用场景 文字大小、颜色

id

layout_width 文本宽度

layout_height 文本高度

text 文本内容,建议引用string.xml中定义的字符串

textColor 字体颜色

textSize 字体大小(单位-sp)

显示不下使用…

maxLines 最大行数

ellipsize [start/middle/end/marquee/none] end是以…结尾

文字+icon

icon要放在drawable下

drawableXxxxx = 图片src, 选择要放置的图片到TextView中文字的x边

drawableRight 选择要放置的图片到TextView中文字的右边

drawablePadding 选择图片的内边距

中划线、下划线

需要通过java代码实现

中划线

private Textview mTv4;//声明控件
@Override
protected void onCreate(Bundle savedInstanceState){
	super.onCreate(savedInstanceState);
	setContentview(R.layout.activity_text_view);
    
	mTv4 = (Textview)findViewById(R.id.tv_4);//找到id对应的控件
	mTv4.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);//设置中划线,此时会有锯齿
	mTv4.getPaint().setAntiAlias(true);//去除锯齿
}

下划线

private Textview mTv5;//声明控件
@Override
protected void onCreate(Bundle savedInstanceState){
	super.onCreate(savedInstancestate);
	setContentview(R.layout.activity_text_view);

    mTv5 = (Textview)findViewById(R.id.tv_5);//指定控件
	mTv5.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);//下划线
}

通过html设置下划线,不用再TextView中声明text属性的具体内容

private TextView mTv6= (TextView) findViewById(R.id.tv_6)
mTv6.setText(Html.fromHtml("李在赣神魔"));
跑马灯文字效果

singleLine 单行显示,设置为true

ellipsize 设置多余文字的显示效果,此处应设置为marquee

marqueeRepeatLimit 文字循环的次数,此处设置为marquee_forever

设置完这些还要设置焦点相关事项

focusable 设置为true

focusableInTouchMode 设置为true

具体代码:

<TextView
	android:id="@+id/tv_7"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="天哥在奔跑天哥在奔跑天哥在奔跑天哥在奔跑"
	android:textColor="#000000"
	android:textsize="24sp"
	android:singleLine="true"
	android:ellipsize="marquee"
	android:marqueeRepeatLimit="marquee_forever"
	android:focusable="true"
	android:focusableInTouchMode="true"/>
Button(TextView的子类)

Button的其他衍生控件:ToggleButton、Switch

需要在mainactivity声明一个私有的Button,并且指明目标button控件。通过findViewById()方法返回view对象并且强转为Button

private Button mBtnTextView =(Button)findViewById(R.id.btn_textview)
特有属性

textAllCaps=“false” 关闭默认所有字母为大写的设定,按照实际text显示

应用场景 文字大小

textSize (单位-sp)

自定义背景形状

background 指定自定义效果。需要在drawable中创建shape根元素文件,

设置圆角按钮

drawable resource file内容

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">//设置按钮形状为矩形
    <solid android:color="#FF9900"></solid>//设置颜色为橙色
    <corners android:radius="10dp"></corners>//设置圆角

</shape>

设置边框,并且里面空白填充

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">//设置按钮形状为矩形
    <stroke //描边效果
    android:width="1dp" //描边线 的宽度
    android:color="#FF9900"></stroke>//设置颜色为橙色
    <corners android:radius="10dp"></corners>//设置圆角

</shape>
自定义按压效果
<?xml version="1.0"encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:state_pressed="true">
		<shape>
			<solid android:color="#AA6600"/>
			<corners android:radius="5dp"/>
		</shape>
	</item>
	<item android:state_pressed="false">
		<shape>
			<solid android:color="#FF9900"/>
			<corners android:radius="5dp"/>
		</shape>
	</item>
</selector>
点击事件(手机底部d出灰色d窗)

方式一:

onClick=“showToast” 这行属性的意思是,点击后调用所在Activity的showToast()方法。

需要在Button内设置该属性,并且在ButtonActivity类写方法的具体内容,仿照下面代码

public class ButtonActivity extends AppCompatActivity{
	@Override
	protected void onCreate(Bundle savedInstancestate){
		super.onCreate(savedInstancestate);
		setContentview(R.layout.activity_button);
	}	
	public void showToast(View view){
		Toast.makeText(this,"我被点击了"Toast.LENGTH_SHORT).show();
    }
}

方式二:给按钮设置点击事件(常用)

在所在的activity中声明一个button对象并且指向存在的按钮。调用这个对象的setOnclickListener(),传入的参数是一个匿名类匿名对象–new View.OnClickListener(),重写该匿名对象中的onClick()方法

private Button mBtn3;
@Override
protected void onCreate(Bundle savedInstancestate){
	super.onCreate(savedInstancestate);
	setContentview(R.layout.activity_button);
	mBtn3 = (Button)findviewById(R.id.btn_3);
	mBtn3.setonclickListener(new View.OnclickListener(){
		@Override
		public void onclick(View v){
			Toast,makeText(ButtonActivity.this,"btn3被点击了"Toast.LENGTH_SHORT).show();
});

TextView同样可以设置点击事件

EditText(TextView的子类)

– 一个可输入的文本框控件

常用(特有)属性

textColor 文本的颜色

hint 用于提示的灰色文字 比如“请输入用户名”

inputType =“textPassword” 设置输入的密码为暗文

inputType=“number” 规定输入字符为数字,并且点击文本框会d出数字键盘

drawableLeft 在文本框的左边设置一张图片

drawablePadding 设置图片的内边距

maxLines 最大行数 通常设为1

自定义background的方法与Button相同设置点击事件

制作登录界面+监听事件(监听控件)

两个edittext用户名、密码,一个button登录按钮

登录成功的效果需要设置监听事件,步骤是 在当前activity声明、指定控件、设置点击效果。可以参照Button中应用场景中点击事件的方式二。

在控制台监听输入用户名的信息
private EditText mEtUserName;
mEtUserName = (EditText)findViewById(R.id.et_1);
mEtUserName.addTextChangedListener(new TextWatcher(){
	@Override
	public void beforeTextChanged(CharSequence s,int start,int count,int 			after){
		}
	@Override
	public void onTextChanged(CharSequence s,int start,int before,int 			count){
				Log.d("edittext",s.tostring());//在控制台监听用户输入的信息
		}
	@Override
	public void afterTextChanged(Editable s){
		}
})
RadioButton(Button子类)

说明:

RadioButton每组超过1个就要使用RadioGroup来包裹RadioGroup是单选,即使每个RadioButton有了background,效果也只会在选中的按钮上显示 常用(特有)属性

textSize 按钮文本大小 单位-sp

checked 默认选中状态(前提是RadioButton要有id,否则失效)

button =“@null” 设置按钮的圆圈消失

RadioGroup属性

orientation 内部按钮排列方式

自定义样式

跟button的background相似,不同之处 ↓

selector中的item标签中的属性

state_checked =“true” 按钮选中状态

stroke标签 描边效果

监听事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-joMGUhHy-1651295481913)(E:\MD笔记\Android学习\image-20220426144553341.png)]

复选框CheckBox 多个复选框不用包裹起来每个复选框可以选中、取消 常用属性

text

textSize --sp

textColor

button =“background_src” 自定义复选框

item属性

state_checked =“true” 被选中的状态是

state_checked ="false"为被选中的状态是

监听事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnZE0Mfj-1651295481915)(E:\MD笔记\Android学习\image-20220426172045219.png)]

ImageView 常用属性

background 背景(颜色/图片)

src 设置一张图片,在background的上层

scaleType src图片在控件里的缩放类型(fitXY:撑满控件,宽高比可能发生改变;fitCenter:保持宽高比缩放,直至能够完全显示;centerCrop:保持宽高比,直至完全覆盖控件,裁剪显示)

ImageVIew对象常用方法

setImageResource 设置图片视图的图片

如何加载网络图片(使用第三方图片加载库glide)

重要说明:当app里需要适用网络文件时需要在AndroidManifest.xml文件里声明use-permission标签

导入方法

方法一:在github搜索glide库,下载该库放在libs文件夹。

方法二:或者使用gradle管理,把github中readme文件里介绍的repositories和dependencies内容复制到gradle。dependencies里的第二个compile不用复制了。说明:当app里需要适用网络文件时需要在AndroidManifest.xml文件里声明use-permission标签

简单使用案例
public class ImageViewActivity extends AppCompatActivity {

    private ImageView mIv4;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_view);
        mIv4 = (ImageView) findViewById(R.id.iv_4);//找到控件,mIv4指定控件
        Glide.with(this).load("http://www.kaotop.com/file/tupian/20220518/bd_logo1_31bdc765.png").into(mIv4);//加载图片,把网络图片地址放在load()里面
    }
}

列表视图ListView(过时,迷迷糊糊) 自定义Activity 创建ListViewActivity,父类是Activity。在AndroidManifest.xml声明该自定义类重写方法onCreat(),setContentView(R.layout.new出来的layout.xml)在新建的xml里,设计具体的ListView 自定义ListView 先自定义Adapter写一个布局, 常用属性

listSelector 指定的selector修饰文件

自定义Adapter接口

自定义MyLIstAdapter,继承于BaseAdapter。

写一个构造器,重写getView(作用是自定义每个网 格怎么实现)方法

private Context mContext;
private LayoutInflatert mLayoutInflatert;

public MyListAdapter(Context context){
	this.mContext=context;
    mLayoutInflatert=LayoutInflater.from(comtext);
}

get view()
点击事件(长按或点击)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xrpRasnE-1651295481916)(E:\MD笔记\Android学习\image-20220426205755978.png)]

网格视图GridView(过时,与ListView相似)

APPCompatActivity和Activity的区别:appcompatactivity有顶部应用名,activity没有

常用属性

numColumns 控制列数

horizontalSpacing 水平网格间距

verticalSpacing 垂直网格间距

Adapter接口

相似

点击事件

相似

滚动视图ScrollView 垂直滚动:ScrollView

子元素只能有一个

把包括LinearLayout在内的控件包裹在ScrollView控件即可实现垂直滚动

水平滚动:HorizontalScrollView

子元素只能有一个

把包括LinearLayout在内的控件包裹在HorizontalScrollView控件即可实现垂直滚动

RecyclerView控件(跳了)

用来代替ListView,GridView,ScrollView

RecyclerViewi能够灵活实现大数据集的展示,视图的复用管理比ListView更好,能够显示列表、网格、瀑布流等形式,且不同的ViewHolder能够实现item多元化的功能。
但是使用起来会稍微麻烦一点,并且没有类似ListView的onItemClickListener监听事件,需要开发者自己实现。

使用前要引入RecyclerView包:在build.gradle的dependencies添加

compile com.android.support:design:25.3.1
//会变换,需要上网搜索查询
LinearRecyclerViewActivity WebView控件 加载网页 加载URL(网络的html文件)

webview.loadUrl(“http://www.m.baidu.com”)

如果没有加载出来,是因为默认不加载js代码,需要设置一下

mWv.Main.getSettings().setJavaScriptEnable

如果跳转到浏览器,没有在应用里打开网页需要设置一下
mWvMain.setWebnViewClient(new MyWebViewClient()); 

class MyWebViewClient extends WebViewClient{//内部类
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.getUrl().toString());
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            Log.d("WebView","onPageStarted...");
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Log.d("WebView","onPageFinished...");
//            mWvMain.loadUrl("javascript:alert('hello')");
            mWvMain.evaluateJavascript("javascript:alert('hello')",null);
        }
    }
当在网页内返回时直接退出activity需要重写一个方法
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK && mWvMain.canGoBack()){
            mWvMain.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
加载本地assets文件夹(放一些不需要编译的文件)

webview.loadUrl(“file:///android_asser/test.html”)

assets文件夹创建在sr0c-main目录下,创建file

加载html代码

webview.loadData();

webview.loadDataWithBaseURL();

网页的前进后退

webview.canGoBack();

webview.goBack();

webview.canGoForward();

webview.goForward();

webview.canGoVackOrForward(int steps)

按下返回键,默认是退出当前Activity,如果希望是VebView内页面后退
@Override
public boolean onKeyDown(int keyCode,KeyEvent event){
	if ((keyCode =KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){
		webview.goBack();
		return true;
		}
        return super.onKeyDown(keyCode,event);
}
UI组件之d出组件 Toast

Toast是一个消息提示组件,可以用于设计Button点击反馈提示效果

设置显示的位置

默认、居中、带图片(自定义)

创建自定义类OnClick实现View.OnClickListener

class OnClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_toast_1://默认效果
                    Toast.makeText(getApplicationContext(),"Toast",Toast.LENGTH_LONG).show();
                    break;
                case R.id.btn_toast_2://居中效果,makeText返回的是一个Toast类型对象,对这个对象进行 *** 作可以改变Toast调用show()时显示的样式
                    Toast toastCenter = Toast.makeText(getApplicationContext(),"居中Toast",Toast.LENGTH_LONG);
                    toastCenter.setGravity(Gravity.CENTER,0,0);
                    toastCenter.show();
                    break;
                case R.id.btn_toast_3://自定义图片效果
                    Toast toastCustom = new Toast(getApplicationContext());
                    LayoutInflater inflater = LayoutInflater.from(ToastActivity.this);
                    View view = inflater.inflate(R.layout.layout_toast,null);
                    ImageView imageView = (ImageView) view.findViewById(R.id.iv_toast);
                    TextView textView = (TextView) view.findViewById(R.id.tv_toast);
                    imageView.setImageResource(R.drawable.icon_smile);
                    textView.setText("自定义Toast");
                    toastCustom.setView(view);
                    toastCustom.setDuration(Toast.LENGTH_LONG);
                    toastCustom.show();
                    break;
                case R.id.btn_toast_4:
                    ToastUtil.showMsg(getApplicationContext(),"包装过的Toast");
                    break;
            }
        }
    }
自定义显示内容

通过Toast对象自定义显示内容

case R.id.btn_toast_3:
                    Toast toastCustom = new Toast(getApplicationContext());
                    LayoutInflater inflater = LayoutInflater.from(ToastActivity.this);
                    View view = inflater.inflate(R.layout.layout_toast,null);
                    ImageView imageView = (ImageView) view.findViewById(R.id.iv_toast);
                    TextView textView = (TextView) view.findViewById(R.id.tv_toast);
                    imageView.setImageResource(R.drawable.icon_smile);
                    textView.setText("自定义Toast");
                    toastCustom.setView(view);
                    toastCustom.setDuration(Toast.LENGTH_LONG);
                    toastCustom.show();
                    break;
Toast对象常用方法/构造器

构造器使用:

Toast toastCustom = new Toast(getApplicationContext());

方法:

setView(view) 设置Toast的视图

setDuration 设置Toast的停留时长

show 显示Toast内容

cancel 多次点击该toast只会叠加一次效果(高版本api无需考虑这个)

说明:

setView方法需要传入一个view,这个view需要通过一个LayouotInflater对象调用inflate方法返回。另外还可以通过指定imageView,通过imageView调用方法自定义显示这些控件的显示内容

简单封装,公具类 ToastUtil
public class ToastUtil {
    public static Toast mToast;
    public static void showMsg(Context context,String msg){
        if(mToast == null){
            mToast = Toast.makeText(context,msg,Toast.LENGTH_LONG);
        }else{
            mToast.setText(msg);
        }
        mToast.show();
    }
}

使用ToastUtil,这种情况只会叠加一次效果,即使没有使用cnacel方法

case R.id.btn_toast_4:
                    ToastUtil.showMsg(getApplicationContext(),"包装过的Toast");
                    break;
AlertDialog警示对话框 AlertDialog.Builder 常用方法

setTitle 设置对话框标题

setMessage 设置对话框内容

setIcon 设置对话框图标

setPositiveButton 设置积极选项按钮(onClick设置按钮的点击事件)

setNeutralButton 设置中性按钮

setNegativeButton 设置消极按钮

setItems 参数可以是数组,设置按钮的内容,可以设置点击事件

setSingleChoiceItems 设置单选(数组,要选择的内容的数组索引,点击事件)

setCancelable(false) 设置-除了点击选项,点击其他地方,对话框不会消失,设置此处后需要在onClick中,show方法调用之后再调用dismiss来达到点击选项后消失的效果

默认样式

步骤:

case R.id.btn_dialog1:
                    AlertDialog.Builder builder = new AlertDialog.Builder(DialogActivity.this);
//链式调用,设置对话框显示效果,以及点击事件
                    builder.setTitle("请回答").setMessage("你觉得课程如何?")
                            .setIcon(R.drawable.icon_user)
                            .setPositiveButton("棒", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    ToastUtil.showMsg(DialogActivity.this, "你很诚实");
                                }
                            }).setNeutralButton("还行", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ToastUtil.showMsg(DialogActivity.this, "你再瞅瞅~");
                        }
                    }).setNegativeButton("不好", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ToastUtil.showMsg(DialogActivity.this, "睁眼说瞎话");
                        }
                    }).show();
                    break;
单选样式

setSingleChoiceItems()

样式一:

case R.id.btn_dialog2:
                    final String[] array2 = new String[]{"男", "女"};
                    AlertDialog.Builder builder2 = new AlertDialog.Builder(DialogActivity.this);
                    builder2.setTitle("选择性别").setItems(array2, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ToastUtil.showMsg(DialogActivity.this, array2[which]);
                        }
                    }).show();
                    break;

样式二:可以默认选中一个值

case R.id.btn_dialog3:
                    final String[] array3 = new String[]{"男", "女"};
                    AlertDialog.Builder builder3 = new AlertDialog.Builder(DialogActivity.this);
                    builder3.setTitle("选择性别").setSingleChoiceItems(array3, 1, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ToastUtil.showMsg(DialogActivity.this, array3[which]);
                            dialog.dismiss();
                        }
                    }).setCancelable(false).show();
                    break;
多选样式

setMultiChoiceItems()

case R.id.btn_dialog4:
                    final String[] array4 = new String[]{"唱歌", "跳舞","写代码"};
                    boolean[] isSelected = new boolean[]{false,false,true};
                    AlertDialog.Builder builder4 = new AlertDialog.Builder(DialogActivity.this);
                    builder4.setTitle("选择兴趣").setMultiChoiceItems(array4, isSelected, new DialogInterface.OnMultiChoiceClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                            ToastUtil.showMsg(DialogActivity.this,array4[which]+":"+isChecked);
                        }
                    }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //
                        }
                    }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    }).show();
                    break;
自定义样式(登录样式)
case R.id.btn_dialog5:
                    AlertDialog.Builder builder5 = new AlertDialog.Builder(DialogActivity.this);
                    View view = LayoutInflater.from(DialogActivity.this).inflate(R.layout.layout_dialog,null);
                    EditText etUserName = (EditText) view.findViewById(R.id.et_username);
                    EditText etPassWord = (EditText) view.findViewById(R.id.et_password);
                    Button btnLogin = (Button) view.findViewById(R.id.btn_login);
                    btnLogin.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            //
                        }
                    });
                    builder5.setTitle("请先登录").setView(view).show();
                    break;
ProgressBar&ProgressDialog ProgressBar 常用属性

style 进度条的风格,默认是 @style/Widget.Material.ProgressBar,有许多种风格,可以在res-values-style中自定义添加一个style,比如

    <style name="MyProgressBar">
        <item name="android:indeterminateDrawable">@drawable/bg_progress</item>//引用一个自定义的drawable文件
    </style>

其中,widget.progressbar.horizontal是有进度的长进度条

progress 设置进度条的进度

secondaryProgress 设置进度条的二级进度

progressDrawable 设计进度条的自定义视图

visibility 控制进度条可见或者不可见

indetertminateDrawable =“@drawable/bg_progress” 替换为自定义drawable文件(

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/icon_progress"//一个图片
    android:pivotX="50%" //设置水平转轴中心
    android:pivotY="50%">//设置垂直

</animated-rotate>

ProgressDialog

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lepJNADi-1651295481924)(E:\MD笔记\Android学习\image-20220427180819486.png)]

ProgressDialog类的常用方法

构造器:

ProgressDialog progressDialog = new ProgressDialog(ProgressActivity.this);

方法:

setProgressStyle 设置样式,可以设置成进度条

setTitle 设置标题

setMessage 设置内容

setOnCancelListener 设置取消行为的监听器

setCancelable =“false” 设置无法取消

show 显示progressdialog

setButton 设置按钮

实例1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S8KlXKSm-1651295481925)(E:\MD笔记\Android学习\image-20220427175430596.png)]

private Button mBtnStart,mBtnProgressDialog1,mBtnProgressDialog2;
mBtnProgressDialog1 = (Button) findViewById(R.id.btn_progress_dialog1);
mBtnProgressDialog1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog progressDialog = new ProgressDialog(ProgressActivity.this);
                progressDialog.setTitle("提示");
                progressDialog.setMessage("正在加载");
                progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        ToastUtil.showMsg(ProgressActivity.this,"cancel...");
                    }
                });
                progressDialog.setCancelable(false);
                progressDialog.show();
            }
        });
实例2

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hZGNwaNR-1651295481925)(E:\MD笔记\Android学习\image-20220427180945868.png)]

     mBtnProgressDialog2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog progressDialog = new ProgressDialog(ProgressActivity.this);
                progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                progressDialog.setTitle("提示");
                progressDialog.setMessage("正在下载...");
                progressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "棒", new DialogInterface.OnClickListener() {//设置按钮
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //
                    }
                });
                progressDialog.show();
            }
        });
自定义Dialog(?) 设置dialog形状(shape)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">//矩形
    <solid android:color="@color/colorWhite"/>//填充颜色
    <corners android:radius="10dp"/>//圆角
</shape>

CustomDialogActivity页面

public class CustomDialogActivity extends AppCompatActivity {

    private Button mBtnDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom);
        mBtnDialog = (Button) findViewById(R.id.btn_custom_dialog);
        mBtnDialog.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CustomDialog customDialog = new CustomDialog(CustomDialogActivity.this);
                customDialog.setTitle("提示").setMessage("确认删除此项?")
                .setCancel("取消", new CustomDialog.IOnCancelListener() {
                    @Override
                    public void onCancel(CustomDialog dialog) {
                        ToastUtil.showMsg(CustomDialogActivity.this,"cancel...");
                    }
                }).setConfirm("确认", new CustomDialog.IOnConfirmListener() {
                    @Override
                    public void onConfirm(CustomDialog dialog) {
                        ToastUtil.showMsg(CustomDialogActivity.this,"confirm...");
                    }
                }).show();
            }
        });
    }
}

自定义的CustomDialog类

public class CustomDialog extends Dialog implements View.OnClickListener{

    private TextView mTvTitle,mTvMessage,mTvCancel,mTvConfirm;

    private String title,message,cancel,confirm;

    private IOnCancelListener cancelListener;

    private IOnConfirmListener confirmListener;

    public CustomDialog(@NonNull Context context) {
        super(context);
    }

    public CustomDialog(@NonNull Context context,int themeId) {
        super(context,themeId);
    }

    public CustomDialog setTitle(String title) {
        this.title = title;
        return this;
    }

    public CustomDialog setMessage(String message) {
        this.message = message;
        return this;
    }

    public CustomDialog setCancel(String cancel,IOnCancelListener listener) {
        this.cancel = cancel;
        this.cancelListener = listener;
        return this;
    }

    public CustomDialog setConfirm(String confirm,IOnConfirmListener listener) {
        this.confirm = confirm;
        this.confirmListener = listener;
        return this;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_custom_dialog);
        //设置宽度
        WindowManager m = getWindow().getWindowManager();
        Display d = m.getDefaultDisplay();
        WindowManager.LayoutParams p = getWindow().getAttributes();
        Point size = new Point();
        d.getSize(size);
        p.width = (int)(size.x * 0.8); //设置dialog的宽度为当前手机屏幕的宽度*0.8
        getWindow().setAttributes(p);

        mTvTitle = (TextView) findViewById(R.id.tv_title);
        mTvMessage = (TextView) findViewById(R.id.tv_message);
        mTvCancel = (TextView) findViewById(R.id.tv_cancel);
        mTvConfirm = (TextView) findViewById(R.id.tv_confirm);
        if(!TextUtils.isEmpty(title)){
            mTvTitle.setText(title);
        }
        if(!TextUtils.isEmpty(message)){
            mTvMessage.setText(message);
        }
        if(!TextUtils.isEmpty(cancel)){
            mTvCancel.setText(cancel);
        }
        if(!TextUtils.isEmpty(confirm)){
            mTvConfirm.setText(confirm);
        }
        mTvCancel.setOnClickListener(this);
        mTvConfirm.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.tv_cancel:
                if(cancelListener != null){
                    cancelListener.onCancel(this);
                }
                dismiss();
                break;
            case R.id.tv_confirm:
                if(confirmListener != null){
                    confirmListener.onConfirm(this);
                }
                dismiss();
                break;
        }
    }

    public interface IOnCancelListener{
        void onCancel(CustomDialog dialog);
    }

    public interface IOnConfirmListener{
        void onConfirm(CustomDialog dialog);
    }
}
PopupWindowd出窗口

可以用于选学科这个功能中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kEsUXkn-1651295481926)(E:\MD笔记\Android学习\image-20220427185151994.png)]

常用方法

setOutsideTouchable =“true” 设置点击外边关闭d出窗口

setFocusable =“true”

showAsDropDown 设置窗口出现在哪个控件的下边

showAtLocation

实例

activity文件:

public class PopupWindowActivity extends AppCompatActivity {

    private Button mBtnPop;
    private PopupWindow mPop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popup_window);
        mBtnPop = (Button) findViewById(R.id.btn_pop);
        mBtnPop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                View view = getLayoutInflater().inflate(R.layout.layout_pop,null);
                TextView textView = (TextView) view.findViewById(R.id.tv_good);
                textView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mPop.dismiss();
                        //do something...
                        ToastUtil.showMsg(PopupWindowActivity.this,"好");
                    }
                });
                mPop = new PopupWindow(view,mBtnPop.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
                mPop.setOutsideTouchable(true);
                mPop.setFocusable(true);
                mPop.showAsDropDown(mBtnPop);
            }
        });
    }
}

页面的设计xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bg_dropdown">

    <TextView
        android:id="@+id/tv_good"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="@color/colorGrayDark"
        android:text="好"
        android:gravity="center"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/colorGrayDark"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="@color/colorGrayDark"
        android:text="还行"
        android:gravity="center"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/colorGrayDark"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="@color/colorGrayDark"
        android:text="不好"
        android:gravity="center"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"/>

</LinearLayout>
不可不会的Activity和Fragment Activity的创建三部曲

步骤:

1.新建类继承Activity或其子类(v7.appcompatactivity)

2.在AndroidManifest中声明。如果想要改变页面的标题,需要在这里的activity标签中设置label属性

3.创建layout并在activity的onCreat中设置

Activity属性

screenOrientation 显示方向,固定垂直或固定竖直;默认跟随手机变化

label 标题

theme 主体

launchMode 启动模式

intent-filter标签 设置为该页面为启动页

taskAffinity =".abcdef"设置任务栈的名称

<intent-filter>
	<action android:name="android.intent..action.MAIN"/
	<category android:name="android.intent.category.LAUNCHER"/
</intent-filter>
如何自定义一个页面标题栏 设置activity的属性theme =[noactionbar无效果],如果想要给每个页面都设置同一个theme,可以在application标签内设置theme效果=noactionbar Activity的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cREPCVD1-1651295481926)(E:\MD笔记\Android学习\image-20220428082453251.png)]如何判断当前activity处于什么状态(通过控制台输出信息)

public class LifeCycleActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        Log.d("LifeCycle","----onCreate----");
    }

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

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

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("LifeCycle","----onPause----");

    }

    @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会进行,oncreat onstart onresume其他地方有占用,造成该activity处于后台的过程中,调用 onPause onStop关闭activity时 onDestory Activity的跳转和数据传递 显式跳转和隐式跳转

通常使用显示1的方式

隐式跳转可以跳转到其他软件?从软件页面跳转到打电话页面?

mBtnJump.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //显式1
                Intent intent = new Intent(AActivity.this, BActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString("name", "天哥");
                bundle.putInt("number", 88);
                intent.putExtras(bundle);
                startActivity(intent);
//                startActivityForResult(intent, 0);

                //显式2
//                Intent intent = new Intent();
//                intent.setClass(AActivity.this,BActivity.class);
//                startActivity(intent);

                //显式3
//                Intent intent = new Intent();
//                intent.setClassName(AActivity.this,"com.skypan.helloworld.jump.BActivity");
//                startActivity(intent);

                //显式4
//                Intent intent = new Intent();
//                intent.setComponent(new ComponentName(AActivity.this,"com.skypan.helloworld.jump.BActivity"));
//                startActivity(intent);

                //隐式
//                Intent intent = new Intent();
//                intent.setAction("com.skypan.test.BActivity");
                //setAction的内容是我们再AndroidManifest中给这个Activity设置的action,可以是任何值,起标识作用;然后设置category为default,具体看下面
//                startActivity(intent);
            }
        });
<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之间的数据传递
//传出:intent:意图
Intent intent = new Intent(AActivity.this, BActivity.class);
                Bundle bundle = new Bundle();
                bundle.putString("name", "天哥");
                bundle.putInt("number", 88);
                intent.putExtras(bundle);
                startActivity(intent);
//接收:
Bundle bundle = getIntent().getExtras();
        String name = bundle.getString("name");
        int number = bundle.getInt("number");
startActivity:启动Activity,结束后返回结果

A页面转到B页面,当需要B页面传输数据到A页面时,就需要使用startActivityForResult(intent,0);

//A页面
startActivityForResult(intent, 0);  

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Toast.makeText(AActivity.this, data.getExtras().getString("title"), Toast.LENGTH_LONG).show();
    }
//B页面
  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);
                setResult(Activity.RESULT_OK,intent);
                finish();
            }
        });
Activity的4种启动方式

Activity的android:launchMode属性(在AndroidManifest里设置):

standard:标准模式singleTop:task栈顶复用模式singleTask:task栈内复用模式singleInstance:全局单例模式 standard

Activity是由任务栈管理的,每启动一个Activity,就会被放入栈中,按返回键,就会从栈顶移除一个Activity。

standard是默认的启动模式,即标准模式。每启动一个Activity,都会创建一个新的实例。

singleTop

当要启动的目标Activity已经位于栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onNewIntent()方法会被调用;如果目标Activity
不在栈顶,则跟standard一样创建新的实例。

singleTask

在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,并且该Activity上面的Activit
y会被清除;如果栈中没有,则创建新的实例。

singleInstance

全局复用,不管哪个Task栈,只要存在目标Activity,就复用。每个Activity占有一个新的Task栈。

Fragment Fragement有自己的生命周期Fragment依赖于ActivityFragmenti通过getActivity()可以获取所在的Activity;Activityi通过FragmentManager的findFragmentById()或findFragmentByTag()获取FragmentFragment和Activity是多对多的关系

fragment.java应添加到目标为framelayout的控件内

常用属性方法

getActivity() 得到所在的Activity

onAttach()设置fragment与所在Activity绑在一起

onDetach 设置fragment

使用步骤

创建fragment自定义.java文件,继承于fragment,创建对应的xml文件,进行fragment碎片设计

重写两个方法,比如

public class BFragment extends Fragment {

    private TextView mTvTitle;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_b,container,false);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //
        mTvTitle = (TextView) view.findViewById(R.id.tv_title);//之后可以对textview进行 *** 作
    }

}

在要使用的Activity里声明一个fragment,然后指向一个这个自定义的fragment自定义.java的实例,把fragment添加到Activity

public class ContainerActivity extends AppCompatActivity implements AFragment.IOnMessageClick{

    private AFragment aFragment;
    private TextView mTvTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_container);
        mTvTitle = (TextView) findViewById(R.id.tv_title);

        //实例化AFragment
        aFragment = AFragment.newInstance("我是参数");
        //把AFragment添加到Activity中,记得调用commit
        getFragmentManager().beginTransaction().add(R.id.fl_container,aFragment,"a").commitAllowingStateLoss();
    }

    public void setData(String text){
        mTvTitle.setText(text);
    }

    @Override
    public void onClick(String text) {
        mTvTitle.setText(text);
    }
}

如何把一个位置的afragment替换为一个bfragment

如果通过点击事件来实现fragment的转换,需要在onClick方法里new一个bfragment,然后getFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).commitAllowingStateLoss();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7nRCkyq-1651295481927)(E:\MD笔记\Android学习\image-20220428180341508.png)]

Fragment中getActivity()为可能null的问题

不太推荐的一种方法是在fragment中声明一个Activity,并且通过重写onAttach()方法,在方法里指定这个Activity,在遇到getActivity()方法的地方,用这个声明的Activity代替

private Activity mActivity;
@Override
public void onAttach(Context context){
	super.onAttach(context);
	mActivity=(Activity) context;
}

这一种方法是,因为fragmet被回收的时候会调用onDestory(),这个时候在onDestory()方法里取消异步任务,从而避免getActivity()为null的情况

向Fragment传递参数

传递参数:在Afragment中创建一个静态方法,这个静态方法可以保证返回的Afragment和原来的Fragment其他参数相同,避免了因为设置参数导致Fragment被重置。然后在获取能传输参数的Afragment地方,调用类方法newInstance()方法,返回一个Fragment

    
public static AFragment newInstance(String title){
        AFragment fragment = new AFragment();
        Bundle bundle = new Bundle();
        bundle.putString("title",title);
        fragment.setArguments(bundle);
        return fragment;
    }

private AFragment aFragment=AFragment.newInstance("我是参数");

接收参数:

@Override
public void onViewCreated(Viewview,@Nullable Bundle savedInstancestate){
	super.onViewCreated(view,savedInstancestate);
	//
	mTvTitle (Textview)view.findviewById(R.id.tv_title);
	if(getArguments()!null){
	mTvTitle.setText(getArguments().getstring("title"));
    }
}
Fragment回退栈
getFragmentManager().beginTransaction().replace(R.id.fL_container,bFragment).addToVackStack(null).commitAllowingstateLoss(); //添加到回退栈,在replace生效之后,按返回键会返回到replace之前的Activity,而不是回到mainactivity

此时后退到Afragment时,实例还是那个实例,但是重新调用了onCreatView,重新构造了视图。但是我们希望返回的时候我们对原来Fragment的改变不被重置。

这时候就需要隐藏之前的构图,再来重新添加一个视图

mBtnChange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(bFragment == null){
                    bFragment = new BFragment();
                }
                Fragment fragment = getFragmentManager().findFragmentByTag("a");
                if(fragment != null){
                   						 getFragmentManager().beginTransaction().hide(fragment).add(R.id.fl_container,bFragment).addToBackStack(null).commitAllowingStateLoss();//若存在目标fragment,先hide,再add
                }else{
                    getFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).addToBackStack(null).commitAllowingStateLoss();//如果存在Fragment,直接replace会重置fragment视图,这是不符合预期的
                }
            }
        });
Fragment和Activity的通信

fragment设置Activity中的控件属性:

方式一(不推荐):在Activity中声明方法,这个方法可以设置Activity中控件的属性,在fragment中调用方法就可以改变Activity中的属性。

方式二:

在Fragment中声明一个IOnMessageClick接口,借口中有一个抽象方法,传入一个形参让Activity必须实现这个Fragment中的这个接口,实现抽象方法在Fragment里的onAttach方法里给声明的IOnMessageClick接口赋值为onAttach的形参context

AFragment中

private IOnMessageClick listener;
public interface IOnMessageClick{
        void onClick(String text);
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            listener = (IOnMessageClick) context;
        }catch (ClassCastException e){
            throw new ClassCastException("Activity 必须实现 IOnMessageClick接口");
        }
    }

  mBtnMessage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                ((ContainerActivity)getActivity()).setData("你好");
                listener.onClick("你好");
            }
        });
必须深刻理解的Android事件处理 基于监听的事件处理机制 监听三要素

Event Source(事件源)按钮

Event(事件) onClick

Event Listener(事件监听器) onclicklistener

实现监听事件的方法 通过内部类实现通过匿名内部类通过事件源所在类实现通过外部类实现布局文件中onClick(针对点击事件)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aFAolQoi-1651295481927)(E:\MD笔记\Android学习\image-20220428232958335.png)]

方式五:布局文件中onClick(针对点击事件)

在控件中声明onClick属性,属性的值可以自定义,但是Activity中必须有一个方法和这个属性值相同

比如值为show时,

public void show(View v){
	switch (v.getId()){
		case R.id.btn_event:
			ToastUtil.showMsg(EventActivity.this,"click...");
			break;
    }
}

给同一事件源添加多个同种类型监听器会怎样?

系统会响应最后一个设置的监听器,前面设置的无效。

布局文件中onClick设置的监听器,认为是最先设置的监听器

基于回调的事件处理机制(跳)

回调机制与监听机制的区别?

回调机制的事件源和事件监听器是绑在一起的,监听机制是三个分开的。

基于回调的事件传播

源码剖析,了解View的事件分发(跳) Handler消息处理

to schedule messages and runnables to be excuted as some
point in the future 未来某事做某事?

to enqueue an action to be performed on a different thread
than you own 线程间通信

常用方法

构造器:Dandler()

方法:

postDelayed (线程,毫秒数) 延迟多长时间

public class HandlerActivity extends AppCompatActivity{
	private Handler mHandler;
	@override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstancestate);
		setContentview(R.layout.activity_handler);
		mHandler = new Handler();
		mHandler.postDelayed(new Runnable(){
			@Override
			public void run(){
			Intent intent = new Intent(HandlerActivity.this,ButtonActivity.class);
			startActivity(intent);
            }
},3686);
    }
}

handleMessage (Message) 发送消息

private Handler mHandler;

mHandler = new Handler(){
	@Override
	public void handleMessage(Message msg){//接收信息
		super.handleMessage(msg);
		switch (msg.what){
		case 1:
			ToastUti1.showMsg(HandlerActivity.this,"线程通信成功")break;
		}
    };
    new Thread(){//发送信息
		@Override
		public void run(){
			super.run();
			Message  message = new Message();
			message.what=1;
			mHandler.sendMessage(message);
        }
	}.start();
}
数据存储 sharedpreference轻量数据储存

xml文件,存储键值对

两个关键:

SharedPreferences

SharedPreferences.Editor

private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
mSharedPreferences= getsharedPreferences("data",MODE_PRIVATE);//获取对象的方法,第二个形参为模式,一般选择private,不让别的软件读/写
mEditor = mSharedPreferences.edit();

//点击事件里:存储数据
	mEditor.putString("name",mEtName.getText().toString());
	mEditor.apply();//这一步是储存数据,apply可以异步储存数据,commit同步储存数据,一般用apply
//点击事件里:获取数据
	mTvContent.setText(mSharedPreferences.getString("name",""));//getString()+SharedPreferences文件里的"键",比如存储的name

该文件储存在/data/data//shared_prefs,该文件默认从系统界面不可打开,可是一般我们直接从程序里获取键的值

Android储存概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RAj1Qwvx-1651295481928)(E:\MD笔记\Android学习\image-20220429223631300.png)]

内部储存指即手机自带储存,外部储存指sd卡等

内部储存目录:

/data/data//shared_prefs
/data/data//databases
/data/data//files
/data/data//cache

通过context.getCacheDir()和context.getFileDir()获取文件内容

外部储存目录:

公有目录(sd卡):
Environment.getExternalStoragePublicDirectory(int type)
私有目录:
/mnt/sdcard/Android/data/data//cache
/mnt/sdcard/Android/data/data//files

File内部储存(安卓系统内置的存储)

是覆盖的储存

自定义两个方法save(),和read()来进行储存数据和读取数据,之后再onClick里调用两个方法,实现存储和读取

存储数据save()

//存储数据
private void save(String content){
	Fileoutputstream fileOutputstream null;
	try{
		fileOutputstream 		openFileOutput(mFileName,MODE_PRIVATE);
		fileoutputstream.write(content.getBytes());
	}
	catch (IOException e){
		e.printstackTrace();
    }
	finally{
		if(fileoutputstream !null){
			try{
				fileoutputstream.close();
            }
        } catch (IOException e){
			e.printstackTrace();
        }
    }
}

读取数据read()

//读取数据
private String read(){
	FileInputstream fileInputstream = null;
	try{
		fileInputstream openFileInput(mFileName);
		byte[]buff new byte[1024];
		StringBuilder sb new StringBuilder("");
		int len =0;
		while ((len fileInputstream.read(buff))>e){
			sb.append(new String(buff,0,len));
			}
	return sb.toString();
	} catch (IOException e){
		e.printstackTrace();
	} finally{
		if(fileInputstream !null){
			try{
				fileInputstream.close();
			} catch (IOException e){
				e.printstackTrace();
			}
		}
    }
	return null;
}

方法运用

mBtnSave.setonclickListener(new View.OnclickListener(){
	@override
	public void onclick(View v){
		save(mEtName.getText().toString());
	});
mBtnShow.setonclickListener(new View.OnclickListener(){
	@override
	public void onclick(View v){
		mTvContent.setText(read());
	});
File外部存储(向sd卡读写)

是覆盖的储存

方式和内部储存相似,往sd卡公有目录储存需要权限,方式是在AndroidManifest中写入:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    //还有一种,加不加都行
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    

还需要在mainactivity中oncreate()中写入:来获取储存权限

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);

save()

//存储数据
private void save(String content){
	FileOutputstream fileOutputstream null;
	try{
//leoutputstream openFiLeoutput(mFtLeName,MODE_PRIVATE);
	File dir=new File(Environment.getExternalFilesDir(null),"skypan");//文件会保存在android/data/appID/file下面
	if(!dir.exists()){//如果目录不存在就new一个
		dir.mkdirs();
    }
	File file = new File(dir,mFileName);//查找一个文件,第二个参数是文件名
	if(!file.exist()){//如果不存在,创建一个
		file.createNewFile();
	}
	fileOutputstream new=FileOutputstream(file);
	fileOutputStream.write(content.getBytes());
    }catch (IOException e){
	e.printstackTrace();
	finally{	
		if(fileOutputStream !null){
            try{
				fileOutputstream.close();
            }
        }catch (IOException e){
			e.printstackTrace();
        }
    }
    }
}

read()

//读取数据
private String read(){
	FileInputstream fileInputstream = null;
	try{
		//fileInputstream = openFileInput(mFileName);
        File file new= new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"skypan",mFiname);//file.separator是斜杠/
        fileInputstream= new FileInputStream(file);
		byte[]buff new byte[1024];
		StringBuilder sb new StringBuilder("");
		int len =0;
		while ((len fileInputstream.read(buff))>e){
			sb.append(new String(buff,0,len));
			}
	return sb.toString();
	} catch (IOException e){
		e.printstackTrace();
	} finally{
		if(fileInputstream !null){
			try{
				fileInputstream.close();
			} catch (IOException e){
				e.printstackTrace();
			}
		}
    }
	return null;
}

广播 LocalBroadcastManager()

只会在应用里传播,不会在系统里传播

利用广播实现两个Activity之间的通讯

不过下面这个例子里的情况一般用startActivityForResult();可以点击一个页面后,回调一个值,前面讲过

实例 自定义一个MyBroadcast类,继承于BroadcastReveiver接收广播:重写receive,传入两个参数(context,intent),判断Intent的action是什么,然后通过action判断要做什么东西发送广播:在需用的地方实例化一个MyBroadcast,然后实例化一个intentfilter,调用intentfilter.addAction(“action的名字”),然后注册广播,调用LocalBroadcastManager的getInstance(this).registerReceiver(MyBroadcast对象,intentfilter对象)

接收广播的自定义类:

private class MyBroadcast extends BroadcastReceiver{
	@Override
	public void onReceive(Contextcontext,Intent intent){
		switch (intent.getAction()){
			case "com.skypan.update":
				mTVTest.setText("123");
				break;	
        }
    }
}

具体运用:

mBroadcast new = MyBroadcast();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.skypan.update");//添加要做哪些动作
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcast,intentFilter);//注册一个广播

最后在关闭Activity时要关闭广播,在onDestory方法里关闭

@Override
protected void onDestroy(){
	super.onDestroy();
	LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcast);
}
属性动画

关于补间动画和属性动画

补间动画只是让你看到了一些动画,但是他的属性没有改变,打印他的xy轴仍然会在原来的位置。属性动画就是属性改变了,从而造成一些动画

常用的两个属性动画:

ValueAnimator

步骤:

声明控件,指明控件

调用控件的animate()方法,然后调用各种动画效果

偏移效果:

tvText.anmate().translationYBy(500).setDutation(2000).start();//translationYBy延y轴偏移500,setDutation设置动作执行的时间(ms),start执行效果

渐变效果:

tvTest.animate().alpha(0).setDuration(2000).start();//两秒内亮度渐变为0

其他实现方法:

VaLueAnimator vaLueAnimator = VaLueAnimator.ofInt(0,100);//让数值从0变到100
vaLueAnimator.setDuration(2000);//设置变化时间
vaLueAnimator.addUpdateListener(new VaLueAnimator.AnimatorUpdateListener(){//设置监听器,监听数值变化
@override
public void onAnimationUpdate(ValueAnimator animation){
	//vaLueAnimator实际的值
	Log.d("aaaa",animation.getAnimatedvalue()+"");//在控制台打印信息
	//动画的进度0-1
	Log.d("aaaa",animation.getAnimatedFraction()+"");
});
vaLueAnimator.start();//开启监听器
ObjectAnimator.ofFloat()

可用 *** 作:translationX / tanslationY / alpha / rotation / rotationX…

使用方法

ObjectAnimator objectAnimator = ObjectAnimator.ofFLoat(tvTest,"translationY",0,500);//让tvTest进行translationY *** 作,从0偏移到500,后边也可以传更多数值参数表示从0到500再到其他地方
objectAnimator.setDuration(2000);//设置动画时间
objectAnimator.start();//开启动画
//也可以设置update监听器监视具体信息

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/992680.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存