Andriod Studio学习
Connect with cellphone
-
turn on the developer rights
-
usb rights & usb 调试 & MTP
-
oppo 可能会出现安装失败,需要在gradle.properties中提交声请
Shortcut Key
-
ctrl+left button,
- then you can see the source code of the methods
-
alt+enter
- use this shortcut key, you can get the most quick solutions to a bug
-
ctrl+p 查看参数提示
-
ctrl+右键,进入该文件
-
ctrl+鼠标放在方法上,可以看到该方法传入的参数
-
double+shift:search any files
-
how to quote the color
- use the rgb numbers directly by #000000
- write needed colors in the values/colors files in advance, when you need, cite the color from the file
-
如何快速写对象的方法
//需要方法来写入具体的title message cancel confirm //右键title 点击generate 选中需要写的方法的对象 可以快速写
testview
- the distinction between linear_layout and relative_layout
- testcolor and testsize 这些对文字的属性设置
- padding margin 这些位置布局
- id的设置一定要养成习惯,因为在其他文件可能会涉及到这个部居,引用的话有id比较方便
Basic learning
- understand the meaning of button and the situation to use button
- relativelayout:id width height test color size backgroud layout_below margin 这些基本设置
- the display of click and the Background for external imports
- how to solve the capitals
- use drawable to set background you want,such as:
- circular bead:
- the reaction of push
- how to import drawable:
- background @drawable + the name of set-background
edittest
-
make loginal interface allow users to input imformation
-
用户登录设置,输入数字的键盘设置,密码不可见如何设置
-
显示出登录成果的提示
-
当出现需要在java文件中书写的部分,如跳转、下浮出显示
- 建立空间
- 找到空间
- 应用空间做你想要的功能
- 用于选项设置
- 单选设置、水平竖直显示设置
4.监听事件:在电脑端反馈出用户输入的信息
CheckBox
- 相比radiobutton,可以实现多选设置
- 引用drawable里面的背景
- 新建drawable文件
- 在该文件中设置想要的背景效果
- 在文件中引用该背景
- 关于如何解决图片过大的问题
ImageView
- 比较重要的scaleType属性(设置缩放类型),类型见2
- common attributes
- fitXY:撑满控件,宽高比可能发生改变
- fitCenter:保持宽高比,直至能够完全显示
- centerCrop:保持宽高比缩放,直至完全覆盖空间,裁剪显示
- loading picture in the internet
- github上的bumptech glide文件
- 通过build.gradle文件导入我们需要的jar包,具体流程可如github上的步骤所示。
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
这里的this和imageview会根据具体情况的不同而不一样,并且应用的是图片的网址
3.在AndriodMainfest.xml文件中声明调用网络权限
List View
- 常用属性
- 通过listSelector去设置按压的一系列效果
- adapter 接口
- adapter文件中主要是getview这个方法的功能,展示的需要的文字
- 具体流程大概是
- 主文件按钮和跳转
- listview.html文件中设置基本属性
- listview.java文件中去实现adapter适配器功能和点击事件
- adapter文件中getview设置
GrideView
- 用法类似于listview,common attributes,分别是numColums:决定显示的列数,horizontalSpring and verticalSpacing 设置上下相隔的间距
-
Adapter接口
-
涉及到控件,也就是adapter的使用,具体步骤如下
- 如果需要用到控件的,可以提前在整个文件包下面新建一个package,单独放这些资料
- 需要在主要的java下面声明GrideView的控件
- 设置相关adapter,需要新建一个adapter.java文件,重写其中的方法
- 其中有四个方法,比较重要的是getview这个方法
- 新建layout文件(不同于原本java文件中的layout文件,主要用于设置布局,主要用于设置之前大的layout文件中,小的部分到底应该如何去排列)
- 回到adapter文件,对getview方法进行完善
- 回到GridViewActivity中引用adapter
ScrollView
-
be used when the elements are too much to be displayed in one page, at this time,we should use scrollview.
-
scrollview是在垂直方向的滚动,horizontalScrollView是在水平方向的滚动
-
如何进行scrollview实现滚动
-
首先要将跟布局从LinearLayout换成Scrollview
-
注意scrollview要求子布局只有一个,如果又多个按钮,可以考虑写一个LinearLayout布局,最后在该布局下放元素,便可以实现滚动
-
当需要水平滚动时,一般是选择嵌套在竖直滚动里面,写一个HorizontalLayout布局,在在该布局中写Linearout布局,然后放元素,就可以实现垂直滚动和竖直滚动
<?xml version="1.0" encoding="utf-8"?> <ScrollView 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=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:id="@+id/btn_textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="textview" ></Button> <Button android:id="@+id/btn_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button"/> <Button android:id="@+id/btn_edittest" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="EditTest" android:textAllCaps="false"/> <Button android:id="@+id/btn_radiobutton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="RadioButton" android:textAllCaps="false"/> <Button android:id="@+id/btn_checkbox" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="CheckBox" android:textAllCaps="false"/> <Button android:id="@+id/btn_imageview" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ImageView" android:textAllCaps="false"/> <Button android:id="@+id/btn_listview" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="ListView" android:textAllCaps="false" /> <Button android:id="@+id/btn_gridview" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="GridView" android:textAllCaps="false" /> <HorizontalScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="200dp" android:layout_height="300dp" android:text="GridView_1" android:textAllCaps="false" /> <Button android:layout_width="200dp" android:layout_height="300dp" android:text="GridView_2" android:textAllCaps="false" /> <Button android:layout_width="200dp" android:layout_height="300dp" android:text="GridView_3" android:textAllCaps="false" /> <Button android:layout_width="200dp" android:layout_height="300dp" android:text="GridView_4" android:textAllCaps="false" /> </LinearLayout> </HorizontalScrollView> </LinearLayout> </ScrollView>
-
RecyclerView_1_list*
- 简介:能够灵活的实现大数据集的展示,视图的复用管理比ListView好,能够显示列表、网络、瀑布流等形式,且不同的ViewHolder能够实现item多元化的功能,其中点击事件需要在自己去实现(onitemclicklistener)
- 主要属性mRvMain.setLayoutManager(new LinearLayoutManager(LinearRecyclerViewActivity.this));
- 再写adapter的时候注意其继承的类是recyclerview的类
- 讲述了一个泛型
- 分割线设置
- 点击事件的设置(接口)
- 具体步骤
RecyclerView_2_grid*
-
水平滚动
-
网格布局
-
基本java文件的写法
public class GridRecyclerViewActivity extends AppCompatActivity { private RecyclerView mRvGrid;//声明空间 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.grid_recycler_view); mRvGrid = findViewById(R.id.rv_grid);//找到空间 //recyclerview中网格状布局的属性设置,一排显示几列 mRvGrid.setLayoutManager(new GridLayoutManager(GridRecyclerViewActivity.this,3)); //适配器,传入一个contest和一个监听事件 //其中监听事件,是在adapter里面通过接口来回调的 mRvGrid.setAdapter(new GridAdapter(GridRecyclerViewActivity.this, new GridAdapter.OnItemClickListener() { @Override public void onClick(int pos) { Toast.makeText(GridRecyclerViewActivity.this,"点击:"+pos,Toast.LENGTH_SHORT).show(); } })); } }
-
适配器设置都基本一样,只是在layout布局文件的引用上会有所差异
package com.example.t04.recyclerview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.example.t04.R; public class GridAdapter extends RecyclerView.Adapter <GridAdapter.LinearViewHolder>{ @NonNull private Context mContext; private OnItemClickListener mlistener; //private List<String> list; public GridAdapter(Context context , OnItemClickListener listener){ this.mContext = context; this.mlistener = listener; } @Override public GridAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new LinearViewHolder(LayoutInflater.from(mContext).inflate(R.layout.layout_hor_item,parent,false)); //这里需要传入每个item长什么样的布局,需要去layout中去画我们的布局 //不同的需求 adapter大体差不多,但是在这里传入的item的布局文件,会因为需要的不同而变化 } @Override public void onBindViewHolder(@NonNull GridAdapter.LinearViewHolder holder, final int position) { holder.textView.setText("Good afternoon "); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Toast.makeText(mContext,"click..."+position,Toast.LENGTH_SHORT).show(); mlistener.onClick(position); } }); } @Override public int getItemCount() { return 50; } class LinearViewHolder extends RecyclerView.ViewHolder{ private TextView textView; public LinearViewHolder(View itemView){ super(itemView); textView = itemView.findViewById(R.id.tv_title); } } //接口 public interface OnItemClickListener{ void onClick(int pos); } }
RecyclerView_3_pu*
-
瀑布流
-
换成图片的形式,那么在adapter中的设置也应该对应换成imageview的形式
package com.example.t04.recyclerview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.example.t04.R; public class StaggeredGridAdapter extends RecyclerView.Adapter <StaggeredGridAdapter.LinearViewHolder>{ @NonNull private Context mContext; private OnItemClickListener mlistener; //private List<String> list; public StaggeredGridAdapter(Context context , OnItemClickListener listener){ this.mContext = context; this.mlistener = listener; } @Override public StaggeredGridAdapter.LinearViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new LinearViewHolder(LayoutInflater.from(mContext).inflate(R.layout.layout_staggered_grid_item,parent,false)); //这里需要传入每个item长什么样的布局,需要去layout中去画我们的布局 //不同的需求 adapter大体差不多,但是在这里传入的item的布局文件,会因为需要的不同而变化 } @Override public void onBindViewHolder(@NonNull StaggeredGridAdapter.LinearViewHolder holder, final int position) { //奇数设置为1,偶数设置为2 if(position % 2 == 0){ holder.imageView.setImageResource(R.drawable.image2); }else{ holder.imageView.setImageResource(R.drawable.image1); } holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Toast.makeText(mContext,"click..."+position,Toast.LENGTH_SHORT).show(); mlistener.onClick(position); } }); } @Override public int getItemCount() { return 30; } class LinearViewHolder extends RecyclerView.ViewHolder{ private ImageView imageView; public LinearViewHolder(View itemView){ super(itemView); imageView = itemView.findViewById(R.id.iv); } } //接口 public interface OnItemClickListener{ void onClick(int pos); } }
-
-
瀑布流所对应的属性设置也有所不同,在原始的java文件中也有一定的改变
package com.example.t04.recyclerview; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; import android.graphics.Rect; import android.os.Bundle; import android.view.View; import android.widget.Toast; import com.example.t04.R; import java.util.concurrent.ThreadPoolExecutor; public class PuRecyclerViewActivity extends AppCompatActivity { private RecyclerView mRvPu; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pu_recycler_view); mRvPu = findViewById(R.id.rv_pu); //2列对应的是verticle //2行则对应的是horizontal mRvPu.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)); mRvPu.addItemDecoration(new Mydecoration()); //如果需要调整分割线或者是间距,这个就必须要加上 mRvPu.setAdapter(new StaggeredGridAdapter(PuRecyclerViewActivity.this, new StaggeredGridAdapter.OnItemClickListener() { @Override public void onClick(int pos) { Toast.makeText(PuRecyclerViewActivity.this,"click:"+pos,Toast.LENGTH_SHORT).show(); } })); } //调整间距 class Mydecoration extends RecyclerView.ItemDecoration{ @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int gap = getResources().getDimensionPixelOffset(R.dimen.dividerHeight2); outRect.set(gap,gap,gap,gap); } } }
RecyclerView_4_dif*
-
不同的ViewHolder
-
首先需要在getItemViewType中去区分不同位置的item,类似于给他们不一样的标签,便于区分
-
然后根据不同的返回值,在onCreateViewHolder和onBindViewHolder两个方法中分别实现不同的item
-
其中需要注意的是,如果有不同的布局,其中textview可能会出错,这个时候需要注意换一下每一方法所继承的类
package com.example.t04.recyclerview; import android.content.Context; import android.provider.ContactsContract; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.example.t04.R; import java.util.List; public class LinearAdapter extends RecyclerView.Adapter <RecyclerView.ViewHolder>{ @NonNull private Context mContext; private OnItemClickListener mlistener; //private List<String> list; public LinearAdapter(Context context ,OnItemClickListener listener){ this.mContext = context; this.mlistener = listener; } @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { //viewType可以通过这个,展示不同的item if(viewType == 0) { return new LinearViewHolder(LayoutInflater.from(mContext).inflate(R.layout.layout_linear_item, parent, false)); }else{ return new LinearViewHolder2(LayoutInflater.from(mContext).inflate(R.layout.layout_linear_item_2,parent,false)); } //这里需要传入每个item长什么样的布局,需要去layout中去画我们的布局 } @Override //通过getItemViewType的返回值来选择具体的item显示 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) { if(getItemViewType(position) == 0){ ((LinearViewHolder)holder).textView.setText("Hello World"); //如果是直接用viewholder的话,是不能用test view的 }else{ ((LinearViewHolder2)holder).textView.setText("就很棒!"); //如果是直接用viewholder的话,是不能用test view的 } //将点击事件放到外面 holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Toast.makeText(mContext,"click..."+position,Toast.LENGTH_SHORT).show(); mlistener.onClick(position); } }); } //去控制viewType的方法,根据位置的奇偶性来区分 @Override public int getItemViewType(int position) { if(position % 2 == 0){ return 0;//偶数 }else{ return 1; } } @Override public int getItemCount() { return 30; } class LinearViewHolder extends RecyclerView.ViewHolder{ private TextView textView; public LinearViewHolder(View itemView){ super(itemView); textView = itemView.findViewById(R.id.tv_title); } } class LinearViewHolder2 extends RecyclerView.ViewHolder{ private TextView textView; private ImageView imageView; public LinearViewHolder2(View itemView){ super(itemView); textView = itemView.findViewById(R.id.tv_title); imageView = itemView.findViewById(R.id.iv_image); //在这里要注意,对应关系,View不要写错了,如果对应错了,不会报错,但是会闪退 } } //接口 public interface OnItemClickListener{ void onClick(int pos); } }
-
-
XRecycleView:addHeadView、addFootView、下拉刷新、上拉加载
WebView
-
加载网页
-
加载URL(网络或者本地assets文件夹下的html文件)
- webview.loadUrl(“http://www.tiantiantech.cn”);
- webview.loadUrl(“file://andriod_asset/test.html”);
-
加载html代码
- webview.loadData();可能会有乱码的现象
- webview.loadDataWithBaseURL();会更好一点
-
Native和javascript相互调用
-
网页的前进和后退
- webview.canGoback();
- webview.goBack();
- webview.canGoForward();
- webview.goForward();
- webview.canGoBackOrForward(int step);
- //前进或者后退的多少
- webview.goBackOrForward(int step);
-
按下返回键,默认是推出当前Activity,如果你希望WEBVIEW页面后退
- 这时候需要重写onKeyDown的方法
-
具体使用
-
首先 html文件中的webview将整个窗口都设置成网页
-
进入java文件中,添加你需要的功能
- 加载,在同一个webview中加载
- 返回,是返回上一级的显示
package com.example.t04; import android.graphics.Bitmap; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.webkit.WebChromeClient; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; public class WebViewActivity extends AppCompatActivity { private WebView mWvMain; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_web_view); mWvMain = findViewById(R.id.wv); //加载本地的html,在assets目录下 //mWvMain.loadUrl("file:///android_asset/index.html"); //加载网络html //如果不加这句的话,需要支持javascript,在手机上是没有办法加载下面那个网页的 mWvMain.getSettings().setJavaScriptEnabled(true); mWvMain.setWebViewClient(new MyWebViewClient()); mWvMain.setWebChromeClient(new MyWebChromeClient()); mWvMain.loadUrl("https://m.baidu.com"); //在手机上搜索,就直接跳转到自己的浏览器了,但是如果直接点击页面上的,就不会跳转到自己的浏览器 } //setWebViewClient这个方法所需要的webviewclient传入信息,t通过这个方法可以继续在webview中加载,而不用跳转到手机自带的浏览器 class MyWebViewClient extends WebViewClient{ @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @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')");//弹出一个对话框,js代码 } } class MyWebChromeClient extends WebChromeClient{ @Override //进度条 public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); //0-100之间 } //设置title @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); setTitle(title); //将网页的title设置到activity的title中去 } } //防止按下返回键,直接退回activity,更希望是返回网页的上一级 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { //如果点击的是返回键并且web中允许返回 if(keyCode == KeyEvent.KEYCODE_BACK & mWvMain.canGoBack()){ mWvMain.goBack(); return true; } return super.onKeyDown(keyCode, event); } }
-
UI组件之弹出组件#
Toast
-
是一个消息提示组件
-
设置显示的位置
-
自定义现实的内容(添加一个图片)
-
注意如果想要直接设置图片的大小,在布局文件跟布局设置不会起作用,需要套一个布局,在里面的布局写
<?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:background="#99000000" android:gravity="center"> <LinearLayout android:layout_width="200dp" android:layout_height="200dp" android:orientation="vertical" android:gravity="center"> <ImageView android:id="@+id/iv_toast" android:layout_width="100dp" android:layout_height="100dp" android:scaleType="fitCenter" /> <TextView android:id="@+id/tv_toast" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="18sp" android:textColor="@color/colorBlue" android:layout_marginTop="10dp"/> </LinearLayout> </LinearLayout>
-
-
简单的封装
-
整体代码
package com.example.t04; import android.os.Bundle; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.example.t04.util.ToastUtil; public class ToastActivity extends AppCompatActivity { private Button mBtnToast1,mBtnToast2,mBtnToast3,mBtnToast4; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_toast); mBtnToast1 = findViewById(R.id.btn_toast_1); mBtnToast2 = findViewById(R.id.btn_toast_2); mBtnToast3 = findViewById(R.id.btn_toast_3); mBtnToast4 = findViewById(R.id.btn_toast_4); OnClick onClick = new OnClick(); mBtnToast1.setOnClickListener(onClick); mBtnToast2.setOnClickListener(onClick); mBtnToast3.setOnClickListener(onClick); mBtnToast4.setOnClickListener(onClick); } 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_SHORT).show(); break; case R.id.btn_toast_2: //相当于把方法拆解了,在拆解的部分上面去加内容 Toast toastCenter = Toast.makeText(getApplicationContext(),"居中Toast",Toast.LENGTH_SHORT);//没有show 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 = view.findViewById(R.id.iv_toast); TextView textView = view.findViewById(R.id.tv_toast); imageView.setImageResource(R.drawable.bg_checkbox); 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; } } } }
2.封装过程
package com.example.t04.util; import android.content.Context; import android.widget.Toast; //进行一个简单的封装 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(); } }
-
-
封装的目的是为了防止点击多次,弹出多次的情况,但是新版的手机安卓端可以在不封装的情况下,也不会重复的弹出。
AlertDialog
-
默认样式
-
单选模式
- 在单选样式的时候有设置点击其他地方不退出的操作
-
多选样式
-
自定义
-
利用的是alertdialog的一个框图,里面的布局时自己画的
package com.example.t04; import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import com.example.t04.util.ToastUtil; public class AlertDialogActivity extends AppCompatActivity { private Button mBtnDialog1,mBtnDialog2,mBtnDialog3,mBtnDialog4,mBtnDialog5; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_alert_dialog); mBtnDialog1 = findViewById(R.id.btn_dialog1); mBtnDialog2 = findViewById(R.id.btn_dialog2); mBtnDialog3 = findViewById(R.id.btn_dialog3); mBtnDialog4 = findViewById(R.id.btn_dialog4); mBtnDialog5 = findViewById(R.id.btn_dialog5); OnClick onClick = new OnClick(); mBtnDialog1.setOnClickListener(onClick); mBtnDialog2.setOnClickListener(onClick); mBtnDialog3.setOnClickListener(onClick); mBtnDialog4.setOnClickListener(onClick); mBtnDialog5.setOnClickListener(onClick); } //set onclick event class OnClick implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()){ case R.id.btn_dialog1: //不要选app下的alertdialog AlertDialog.Builder builder = new AlertDialog.Builder(AlertDialogActivity.this); builder.setTitle("请回答").setMessage("你觉得课程如何?") .setIcon(R.drawable.image1)//在请回答的前面会有一个图片出现 .setPositiveButton("棒",new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { ToastUtil.showMsg(AlertDialogActivity.this,"你很诚实"); } }).setNeutralButton("还行", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ToastUtil.showMsg(AlertDialogActivity.this,"你再看看"); } }).setNegativeButton("不好", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ToastUtil.showMsg(AlertDialogActivity.this,"睁眼说瞎话"); } }).show(); break; case R.id.btn_dialog2: final String[] array2 = new String[]{"男","女"}; AlertDialog.Builder builder2 = new AlertDialog.Builder(AlertDialogActivity.this); builder2.setTitle("选择性别").setItems(array2, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ToastUtil.showMsg(AlertDialogActivity.this,array2[which]); } }).show(); break; case R.id.btn_dialog3: final String[] array3 = new String[]{"男","女"}; AlertDialog.Builder builder3 = new AlertDialog.Builder(AlertDialogActivity.this); builder3.setTitle("请选择性别"); //中间的值是选择默认的是数组的哪一位的值 builder3.setSingleChoiceItems(array3, 1, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ToastUtil.showMsg(AlertDialogActivity.this,array3[which]); dialog.dismiss(); } }).setCancelable(false).show(); //避免点击非对话框部分,对话框消失,如果要加上setcancel的话,不要忘了前面的dismiss // ,不然退不出去 break; case R.id.btn_dialog4: final String[] array4 = new String[]{"唱个歌","跳舞","敲代码"}; boolean[] isSelected = new boolean[]{false,false,true}; AlertDialog.Builder builder4 = new AlertDialog.Builder(AlertDialogActivity.this); builder4.setTitle("选择兴趣").setMultiChoiceItems(array4, isSelected, new DialogInterface.OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { ToastUtil.showMsg(AlertDialogActivity.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; //自定义,去自己画一个layout,利用的是alertdialog的一个框 case R.id.btn_dialog5: AlertDialog.Builder builder5 = new AlertDialog.Builder(AlertDialogActivity.this); View view = LayoutInflater.from(AlertDialogActivity.this).inflate(R.layout.layout_dialog,null); EditText etUsersname = view.findViewById(R.id.et_usersname); EditText etPassword = view.findViewById(R.id.et_password); Button btnLogin = view.findViewById(R.id.btn_login); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //点击完登录后的一些操作 } }); builder5.setTitle("请先登录").setView(view).show(); break; } } } }
-
ProgressBar
-
进度加载的过程、loading
-
在progress控件里面的style中可以又一系列设置
-
选择自己需要的类型即可,有状态无状态
-
style="@android:style/Widget.ProgressBar"
4. 可以设置显示的样式,横向进度条的进度显示 ```hwml <ProgressBar android:id="@+id/pb3" android:layout_width="match_parent" android:layout_height="wrap_content" style="@android:style/Widget.ProgressBar.Horizontal" android:layout_marginTop="10dp" android:progressDrawable="@color/colorBlue" android:max="100" android:progress="20" android:secondaryProgress="50"/>
-
-
对话框显示正在加载
-
下载进度的进度条,可以自己模拟一个下载进度,利用handle
-
使用自己的图片,需要新建一个draw able文件,并在该文件中设置图片的形式,比如绕中心轴旋转之类的
<?xml version="1.0" encoding="utf-8"?> <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/loading" android:pivotX="50%" android:pivotY="50%" > </animated-rotate>
-
也可以通过style去自定义自己的图片,显示加载的形式
- 在styles文件中引用该图片的drawable文件即可
- 然后再总体布局文件中引用这种style即可
ProgressDialog
-
弹出一个框显示进度情况,
mBtnProgressDialog1 = findViewById(R.id.btn_progress_dialog1); mBtnProgressDialog2 = findViewById(R.id.btn_progress_dialog2); mBtnProgressDialog1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //弹出一个prodialog 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(); } }); 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.show(); } }); }
-
但是现在progressDialog的方法已经弃用,实际开发中要去找现在最新的方法是什么
-
全部的代码如下
package com.example.t04;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.example.t04.util.ToastUtil;
public class ProgressActivity extends AppCompatActivity {
private ProgressBar mPb3;
private Button mBtnStart;
private Button mBtnProgressDialog1,mBtnProgressDialog2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress);
mPb3 = findViewById(R.id.pb3);
mPb3.setProgress(30);//设置其进度
mBtnStart = findViewById(R.id.btn_start);
mBtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(0);
//这是一个模拟进程,每次0.5s加5
}
});
mBtnProgressDialog1 = findViewById(R.id.btn_progress_dialog1);
mBtnProgressDialog2 = findViewById(R.id.btn_progress_dialog2);
mBtnProgressDialog1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//弹出一个prodialog
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();
}
});
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, "well", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//点击之后的一些操作
}
});
progressDialog.show();
}
});
}
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(mPb3.getProgress() < 100) {
handler.postDelayed(runnable,500);//0.5s
}else{
ToastUtil.showMsg(ProgressActivity.this,"加载完成");
}
}
};
Runnable runnable = new Runnable() {
@Override
public void run() {
mPb3.setProgress(mPb3.getProgress() + 5);
handler.sendEmptyMessage(0);
}
};
}
Customized Dialog
package com.example.t04.widget;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.example.t04.R;
public class CustomDialog extends Dialog implements View.OnClickListener {
//声明了布局文件中的四个控件
private TextView mTvTitle,mTvMessage,mTvCancel,mTvConfirm;
//需要方法来写入具体的title message cancel confirm
//右键title 点击generate 选中需要写的方法的对象 可以快速写
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 = findViewById(R.id.tv_title);
mTvMessage = findViewById(R.id.tv_message);
mTvCancel = findViewById(R.id.tv_cancel);
mTvConfirm = findViewById(R.id.tv_confirm);
if (!TextUtils.isEmpty(title)) {
mTvTitle.setText(title);//再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:
cancelListener.onCancel(this);
dismiss();
break;
case R.id.tv_confirm:
confirmListener.onConfirm(this);
dismiss();
break;
}
}
public interface IOnCancelListener{
void onCancel(CustomDialog dialog);
}
public interface IOnConfirmListener{
void onConfirm(CustomDialog dialog);
}
}
package com.example.t04;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import com.example.t04.util.ToastUtil;
import com.example.t04.widget.CustomDialog;
public class CustomDialogActivity extends AppCompatActivity {
private Button mBtnDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_dialog);
mBtnDialog = findViewById(R.id.btn_custom_dialog);
//布局文件中的文字仅仅是作为参考,最后的文字还是这里的设置来决定的
mBtnDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CustomDialog customDialog = new CustomDialog(CustomDialogActivity.this, R.style.CustomDialog);
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();
}
});
}
}
<?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_horizontal"
android:background="@drawable/bg_custom_dialog"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@color/colorBlack"
android:text="提示"
android:textStyle="bold"
android:layout_marginTop="15dp"/>
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@color/colorBlack"
android:text="删除?"
android:layout_marginTop="15dp"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/colorBlack"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="取消"
android:textSize="20sp"
android:textColor="@color/colorRed"
android:gravity="center"/>
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/colorBlack"/>
<TextView
android:id="@+id/tv_confirm"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="确定"
android:textSize="20sp"
android:textColor="@color/colorBlue"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>
PopupWindow
-
弹出一个popupwindow,首先需要画一个单独的layout文件
-
利用下面代码可以实现调用该布局文件
View view = getLayoutInflater().inflate(R.layout.layout_pop,null); mPop = new PopupWindow(view,mBtnPOP.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
-
同时还具有一些触摸和动画设置,设置完成之后,要利用showAsDropDown的方法来展示出来
-
也可以设置点击popupwindow窗口的点击事件
TextView textView = view.findViewById(R.id.tv_good); //需要用到该控件的时候一定要提前声明,在那个view里面就用该view去找到控件 textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPop.dismiss(); ToastUtil.showMsg(PopupWindowActivity.this,"你说的真棒!"); } });
Activity&Fragment#
Activity创建三部曲
-
新建类继承activity或者其子类
-
在AndriodMainifest中声明
-
创建layout文件并在Activity的onCreate中设置
-
activty的一些属性
-
如何改变app上方文件(一般显示的是这个项目的名字t04)
-
在mainifest里面的mainactivty中设置label
<activity android:name=".MainActivity" android:label="小冷App"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
-
如何改变上面的界面,如果想所有的界面没有标题,使用自己画的标题,可以在application下的theme写:android:theme="@style/Theme.AppCompat.Light.NoActionBar",但是要注意如果想要某个界面有标题的话,就不要再appliance中写上面那一句话
-
启动模式launchMode
-
Activity的生命周期
- oncreate onstart onstop onpause ondestroy onrestart onresume
- 观看的话就可以在Run下面看具体打印的日志
- 其应用情况,比如正在看电影,来了电话,需要先将看电影暂停,接完电话后继续之前的应用 onpause
Activity的跳转和数据传递
-
显示跳转和隐式跳转
- 在跳转前的java文件中通过代码完成跳转
-
activity之间的数据传递
- 需要在传送数据的java文件中确定需要传递的东西
- 在接收文件的java文件中选择控件接收其数据
-
startActivityForResult:启动Activity,结束后返回结果
-
A文件代码
package com.example.t04.jump; 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.example.t04.R; public class AAActivity extends AppCompatActivity { private Button mBtnJump; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a_a); mBtnJump = findViewById(R.id.btn_jump); mBtnJump.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //当点击该按钮后实现显示跳转,从AA-BB Intent intent = new Intent(AAActivity.this,BBActivity.class); //实现数据传递 Bundle bundle = new Bundle(); bundle.putString("name","小冷"); bundle.putInt("number",578018334); intent.putExtras(bundle); //startActivity(intent); //从跳转目的文件返回的时候,希望能返回一些数据 startActivityForResult(intent,0); //避免有多个地方用到这个方法 //方法二 // Intent intent = new Intent(); // intent.setClass(AAActivity.this,BBActivity.class); // startActivity(intent); //方法三 // Intent intent = new Intent(); // intent.setClassName(AAActivity.this,"com.example.t04.jump.BBActivity"); // //这里是写跳转的完整路径 // startActivity(intent); //方法四 // Intent intent = new Intent(); // intent.setComponent(new ComponentName(AAActivity.this,"com.example.t04.jump.BBActivity")); // startActivity(intent); // //隐式调用 // Intent intent = new Intent(); // intent.setAction("android.intent.B"); // //需要在mainifest BBactivity文件中改一下name和category的文件 // startActivity(intent); } }); } //接收跳转到的界面返回的数据 @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); Toast.makeText(AAActivity.this,data.getExtras().getString("title"),Toast.LENGTH_LONG).show(); } }
-
B文件代码
package com.example.t04.jump; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.t04.R; public class BBActivity extends AppCompatActivity { private TextView mTvData; private Button mBtnFinish; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b_b); mTvData = findViewById(R.id.tv_data); mBtnFinish = findViewById(R.id.btn_finish); //接收数据 final Bundle bundle = getIntent().getExtras(); String name = bundle.getString("name"); int num = bundle.getInt("number"); mTvData.setText(name +":" + num); //返回的时候返回数据 mBtnFinish.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putString("title","I am coming back"); intent.putExtras(bundle); setResult(AAActivity.RESULT_OK,intent); finish(); } }); } }
-
B文件的 布局文件还要设置相关的这个控件,方便显示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".jump.BBActivity">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="恭喜泥完成跳转"
android:gravity="center"
android:textSize="20sp"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/tv_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@color/colorBlack"
android:gravity="center"
android:layout_marginTop="20dp"/>
<Button
android:id="@+id/btn_finish"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Return"
android:layout_marginTop="10dp"
/>
</LinearLayout>
Activity的启动模式
Activity的andriod:launchMode属性
- standard:标准模式,默认
- Activity是由任务栈管理的,每启动一个activity就会被放入栈中,按返回键就会从栈顶移除一个activity
- 每启动一个activity,都会创建一个实例,比如同一个文件跳转到自身,其hash码会有所不同
- singleTop:Task栈顶复用模式
- **当要启动的activity已经位于栈顶时,不会创建新的实例,会复用栈顶的activity,**并且其onNewIntent()的方法会被调用;如果目标的activity不在栈顶,则跟standard一样创建新的实例
- singleTask:Task栈内复用模式
- **在同一个任务栈中,如果启动的activity已经在栈中,则会复用activity,**并调用onNewIntent的方法,并且该activity是上的activity会被清除,如果栈中没有,则会新建
- singleInstance:全局单例模式
- 全局复用,不管哪个Task栈,只要存在目标Activity,就复用,每个activity占有一个新的task栈
Fragment详解
-
fragment有自己的生命周期
-
fragment依赖于activity
-
fragment可以通过getactivity()的方法获取所在的activity,activity通过fragmentmanager的findfragmentbyid()或findfragmentbytag获取frgment
-
fragment与activity是多对多的关系
-
具体步骤
- 主要布局文件中一个button跳转到container文件中,在该布局中设置一个fragment布局,新建两个class和layout文件,放fragment的布局,在container的java文件中实现fragment文件的调用或者替换
-
fragment中getactivity()为null的问题
-
向fragment中传入一个参数
-
首先不是new afragment,而是现在AFragment的java文件里面写一个可以传参数的方法,在container中调用该方法传入想要传入的东西,最后在afragment中接收该值
package com.example.t04.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 com.example.t04.R; public class AFragment extends Fragment { private TextView mTvtitle; // private Activity mActivity; //需要传参数,重新给afragment传递一个可以传参数的方法 public static AFragment newInstance(String title){ AFragment fragment = new AFragment(); //在需要传参的时候,通常需要bundle作为中间变量 Bundle bundle = new Bundle(); bundle.putString("title", title); fragment.setArguments(bundle); return fragment; } @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); //在这里找到view对应的layout布局中的一些控件,对其进行一些设置 mTvtitle = view.findViewById(R.id.tv_title); //去获取传过来的值 if(getArguments() != null){ mTvtitle.setText(getArguments().getString("title")); } } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); // mActivity = (Activity) context; } @Override public void onDetach() { super.onDetach(); } //运行这个方法的时候,getactivity会是null @Override public void onDestroy() { super.onDestroy(); //取消异步 } }
-
-
Fragment回退栈
package com.example.t04.fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.t04.R;
public class AFragment extends Fragment {
private TextView mTvtitle;
private Button mBtnChange;
private Button mBtnReset;
private BFragment bFragment;
// private Activity mActivity;
//需要传参数,重新给afragment传递一个可以传参数的方法
public static AFragment newInstance(String title){
AFragment fragment = new AFragment();
//在需要传参的时候,通常需要bundle作为中间变量
Bundle bundle = new Bundle();
bundle.putString("title", title);
fragment.setArguments(bundle);
return fragment;
}
@Nullable
@Override
//常用方法,返回一个视图,相当于一个布局文件
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a,container,false);
Log.d("Afragment","---onCreateView---");
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//在这里找到view对应的layout布局中的一些控件,对其进行一些设置
mTvtitle = view.findViewById(R.id.tv_title);
mBtnChange = view.findViewById(R.id.btn_change);
mBtnReset = view.findViewById(R.id.btn_reset);
mBtnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(bFragment == null) {
bFragment = new BFragment();
}
Fragment fragment = getFragmentManager().findFragmentByTag("a");//这个tag在container文件中进行设置
if(fragment != null){
getFragmentManager().beginTransaction().hide(fragment).add(R.id.f1_container, bFragment).addToBackStack(null).commitAllowingStateLoss();
}else{
getFragmentManager().beginTransaction().replace(R.id.f1_container, bFragment).addToBackStack(null).commitAllowingStateLoss();
}
// getSupportFragmentManager().beginTransaction().replace(R.id.f1_container, bFragment).commitAllowingStateLoss();
//当有addtoback..的方法时,可以返回到前一个界面,而不是开始的界面,但是调用replace其实返回的时候时新建一个新的界面,这样的话跟换的文字就不能显示出来
}
});
mBtnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mTvtitle.setText("恭喜泥完成替换");
}
});
//去获取传过来的值
if(getArguments() != null){
mTvtitle.setText(getArguments().getString("title"));
}
}
}
- fragment和activity的通信
- 利用接口来实现数据传递
第五章
必须深刻理解的andriod事件处理
-
监听三要素
- Event Source
- Event
- Event Listener
-
实现监听的方法
-
通过内部类实现mBtnEvent.setOnClickListener(new OnClick());
-
通过匿名内部类实现
-
通过事件源所在类实现
- 让该类去实现接口
-
通过外部类实现
-
新建一个java文件实现onclickliatener的方法
-
在需要的文件中调用该方法
//通过外部类实现
mBtnEvent.setOnClickListener(new MyClickListener(EventActivity.this));package com.example.t04; import android.app.Activity; import android.view.View; import com.example.t04.util.ToastUtil; public class MyClickListener implements View.OnClickListener { private Activity mActivity; public MyClickListener (Activity activity){ this.mActivity = activity; } @Override public void onClick(View v) { ToastUtil.showMsg(mActivity,"click4..."); } }
-
-
布局文件中onClick属性(优先级最低)
-
基于回调的事件处理
-
回调机制和监听机制的区别
- 回调事件,是由控件向acticity传播
-
基于回调的事件传播
- 如果需要一层一层的传播一定是return false
- 如果想在那一层停止,在该层换成return true即可
-
注意在新建一个class文件继承某一类的时候,一定要注意把里面的方法写全,不然会炸
-
监听优先于回调
源码剖析,了解View的事件分发
- dispatchTouchEvent–>setOnTouchListener—>onTouchEvent
- dispatchTouchEvent相当于一个入口
- onClick/onLongClick来自onTouchEvent的处理
Handler消息处理
-
主要用途:
-
未来某时做某事
-
线程间通信
package com.example.t04; import android.os.Bundle; import android.os.Handler; import android.os.Message; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.example.t04.util.ToastUtil; public class HandlerActivity extends AppCompatActivity { //delay 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); // } // }, 3000); //接收消息做出判断 mHandler = new Handler(){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: ToastUtil.showMsg(HandlerActivity.this,"线程通信成功"); break; } } }; //线程发送消息 new Thread(){ @Override public void run() { super.run(); Message message = new Message(); message.what = 1; mHandler.sendMessage(message); } }.start(); } }
-