Android Studio学习笔记


Andriod Studio学习

B站主页

Connect with cellphone

  1. turn on the developer rights

  2. usb rights & usb 调试 & MTP

  3. oppo 可能会出现安装失败,需要在gradle.properties中提交声请

Shortcut Key

  1. ctrl+left button,

    1. then you can see the source code of the methods
  2. alt+enter

    1. use this shortcut key, you can get the most quick solutions to a bug
  3. ctrl+p 查看参数提示

  4. ctrl+右键,进入该文件

  5. ctrl+鼠标放在方法上,可以看到该方法传入的参数

  6. double+shift:search any files

  7. how to quote the color

    1. use the rgb numbers directly by #000000
    2. write needed colors in the values/colors files in advance, when you need, cite the color from the file1584107439668
  8. 如何快速写对象的方法

    //需要方法来写入具体的title message cancel confirm
    //右键title 点击generate 选中需要写的方法的对象 可以快速写

testview

  1. the distinction between linear_layout and relative_layout
  2. testcolor and testsize 这些对文字的属性设置
  3. padding margin 这些位置布局
  4. id的设置一定要养成习惯,因为在其他文件可能会涉及到这个部居,引用的话有id比较方便

Basic learning

button

  1. understand the meaning of button and the situation to use button
  2. relativelayout:id width height test color size backgroud layout_below margin 这些基本设置
  3. the display of click and the Background for external imports
  4. how to solve the capitals
  5. use drawable to set background you want,such as:
    1. circular bead:
    2. the reaction of push
    3. how to import drawable:
      1. background @drawable + the name of set-background

edittest

  1. make loginal interface allow users to input imformation

  2. 用户登录设置,输入数字的键盘设置,密码不可见如何设置

  3. 显示出登录成果的提示

  4. 当出现需要在java文件中书写的部分,如跳转、下浮出显示

    1. 建立空间
    2. 找到空间
    3. 应用空间做你想要的功能

radiobutton

  1. 用于选项设置
  2. 单选设置、水平竖直显示设置

4.监听事件:在电脑端反馈出用户输入的信息

CheckBox

  1. 相比radiobutton,可以实现多选设置
  2. 引用drawable里面的背景
    1. 新建drawable文件
    2. 在该文件中设置想要的背景效果
    3. 在文件中引用该背景
    4. 关于如何解决图片过大的问题

ImageView

  1. 比较重要的scaleType属性(设置缩放类型),类型见2
  2. common attributes
    1. fitXY:撑满控件,宽高比可能发生改变
    2. fitCenter:保持宽高比,直至能够完全显示
    3. centerCrop:保持宽高比缩放,直至完全覆盖空间,裁剪显示
  3. loading picture in the internet
    1. github上的bumptech glide文件
    2. 通过build.gradle文件导入我们需要的jar包,具体流程可如github上的步骤所示。

Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);

这里的this和imageview会根据具体情况的不同而不一样,并且应用的是图片的网址

​ 3.在AndriodMainfest.xml文件中声明调用网络权限

List View

  1. 常用属性
    1. 通过listSelector去设置按压的一系列效果
  2. adapter 接口
    1. adapter文件中主要是getview这个方法的功能,展示的需要的文字
  3. 具体流程大概是
    1. 主文件按钮和跳转
    2. listview.html文件中设置基本属性
    3. listview.java文件中去实现adapter适配器功能和点击事件
    4. adapter文件中getview设置

GrideView

  1. 用法类似于listview,common attributes,分别是numColums:决定显示的列数,horizontalSpring and verticalSpacing 设置上下相隔的间距

  1. Adapter接口

  2. 涉及到控件,也就是adapter的使用,具体步骤如下

    1. 如果需要用到控件的,可以提前在整个文件包下面新建一个package,单独放这些资料
    2. 需要在主要的java下面声明GrideView的控件
    3. 设置相关adapter,需要新建一个adapter.java文件,重写其中的方法
      1. 其中有四个方法,比较重要的是getview这个方法
    4. 新建layout文件(不同于原本java文件中的layout文件,主要用于设置布局,主要用于设置之前大的layout文件中,小的部分到底应该如何去排列)
    5. 回到adapter文件,对getview方法进行完善
    6. 回到GridViewActivity中引用adapter

ScrollView

  1. be used when the elements are too much to be displayed in one page, at this time,we should use scrollview.

  2. scrollview是在垂直方向的滚动,horizontalScrollView是在水平方向的滚动

  3. 如何进行scrollview实现滚动

    1. 首先要将跟布局从LinearLayout换成Scrollview

    2. 注意scrollview要求子布局只有一个,如果又多个按钮,可以考虑写一个LinearLayout布局,最后在该布局下放元素,便可以实现滚动

    3. 当需要水平滚动时,一般是选择嵌套在竖直滚动里面,写一个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*

  1. 简介:能够灵活的实现大数据集的展示,视图的复用管理比ListView好,能够显示列表、网络、瀑布流等形式,且不同的ViewHolder能够实现item多元化的功能,其中点击事件需要在自己去实现(onitemclicklistener)
  2. 主要属性mRvMain.setLayoutManager(new LinearLayoutManager(LinearRecyclerViewActivity.this));
  3. 再写adapter的时候注意其继承的类是recyclerview的类
  4. 讲述了一个泛型
  5. 分割线设置
  6. 点击事件的设置(接口)
  7. 具体步骤

RecyclerView_2_grid*

  1. 水平滚动

  2. 网格布局

  3. 基本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();
                }
            }));
        }
    }
  4. 适配器设置都基本一样,只是在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*

  1. 瀑布流

    1. 换成图片的形式,那么在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);
          }
      }
  2. 瀑布流所对应的属性设置也有所不同,在原始的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*

  1. 不同的ViewHolder

    1. 首先需要在getItemViewType中去区分不同位置的item,类似于给他们不一样的标签,便于区分

    2. 然后根据不同的返回值,在onCreateViewHolder和onBindViewHolder两个方法中分别实现不同的item

    3. 其中需要注意的是,如果有不同的布局,其中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);
          }
      }
  2. XRecycleView:addHeadView、addFootView、下拉刷新、上拉加载

WebView

  1. 加载网页

  2. 加载URL(网络或者本地assets文件夹下的html文件)

    1. webview.loadUrl(“http://www.tiantiantech.cn”);
    2. webview.loadUrl(“file://andriod_asset/test.html”);
  3. 加载html代码

    1. webview.loadData();可能会有乱码的现象
    2. webview.loadDataWithBaseURL();会更好一点
  4. Native和javascript相互调用

  5. 网页的前进和后退

    1. webview.canGoback();
    2. webview.goBack();
    3. webview.canGoForward();
    4. webview.goForward();
    5. webview.canGoBackOrForward(int step);
      1. //前进或者后退的多少
    6. webview.goBackOrForward(int step);
  6. 按下返回键,默认是推出当前Activity,如果你希望WEBVIEW页面后退

    1. 这时候需要重写onKeyDown的方法
  7. 具体使用

    1. 首先 html文件中的webview将整个窗口都设置成网页

    2. 进入java文件中,添加你需要的功能

      1. 加载,在同一个webview中加载
      2. 返回,是返回上一级的显示
      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

  1. 是一个消息提示组件

  2. 设置显示的位置

  3. 自定义现实的内容(添加一个图片)

    1. 注意如果想要直接设置图片的大小,在布局文件跟布局设置不会起作用,需要套一个布局,在里面的布局写

      <?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>
  4. 简单的封装

    1. 整体代码

      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();
        }
    
    }
  5. 封装的目的是为了防止点击多次,弹出多次的情况,但是新版的手机安卓端可以在不封装的情况下,也不会重复的弹出。

AlertDialog

  1. 默认样式

  2. 单选模式

    1. 在单选样式的时候有设置点击其他地方不退出的操作
  3. 多选样式

  4. 自定义

    1. 利用的是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

  1. 进度加载的过程、loading

    1. 在progress控件里面的style中可以又一系列设置

    2. 选择自己需要的类型即可,有状态无状态

    3. 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"/>
  2. 对话框显示正在加载

  3. 下载进度的进度条,可以自己模拟一个下载进度,利用handle

  4. 使用自己的图片,需要新建一个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>
  5. 也可以通过style去自定义自己的图片,显示加载的形式

    1. 在styles文件中引用该图片的drawable文件即可
    2. 然后再总体布局文件中引用这种style即可

ProgressDialog

  1. 弹出一个框显示进度情况,

        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();
            }
        });
    }
  2. 但是现在progressDialog的方法已经弃用,实际开发中要去找现在最新的方法是什么

  3. 全部的代码如下

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

  1. 弹出一个popupwindow,首先需要画一个单独的layout文件

  2. 利用下面代码可以实现调用该布局文件

    View view = getLayoutInflater().inflate(R.layout.layout_pop,null);
    mPop = new PopupWindow(view,mBtnPOP.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
  3. 同时还具有一些触摸和动画设置,设置完成之后,要利用showAsDropDown的方法来展示出来

  4. 也可以设置点击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创建三部曲

  1. 新建类继承activity或者其子类

  2. 在AndriodMainifest中声明

  3. 创建layout文件并在Activity的onCreate中设置

  4. activty的一些属性

    1. 如何改变app上方文件(一般显示的是这个项目的名字t04)

    2. 在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>
    3. 如何改变上面的界面,如果想所有的界面没有标题,使用自己画的标题,可以在application下的theme写:android:theme="@style/Theme.AppCompat.Light.NoActionBar",但是要注意如果想要某个界面有标题的话,就不要再appliance中写上面那一句话

    4. 启动模式launchMode

Activity的生命周期

  1. oncreate onstart onstop onpause ondestroy onrestart onresume
  2. 观看的话就可以在Run下面看具体打印的日志
  3. 其应用情况,比如正在看电影,来了电话,需要先将看电影暂停,接完电话后继续之前的应用 onpause

Activity的跳转和数据传递

  1. 显示跳转和隐式跳转

    1. 在跳转前的java文件中通过代码完成跳转
  2. activity之间的数据传递

    1. 需要在传送数据的java文件中确定需要传递的东西
    2. 在接收文件的java文件中选择控件接收其数据
  3. startActivityForResult:启动Activity,结束后返回结果

  4. 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();
        }
    }
  5. 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();
                }
            });
        }
    }
  6. 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属性

  1. standard:标准模式,默认
    1. Activity是由任务栈管理的,每启动一个activity就会被放入栈中,按返回键就会从栈顶移除一个activity
    2. 每启动一个activity,都会创建一个实例,比如同一个文件跳转到自身,其hash码会有所不同
  2. singleTop:Task栈顶复用模式
    1. **当要启动的activity已经位于栈顶时,不会创建新的实例,会复用栈顶的activity,**并且其onNewIntent()的方法会被调用;如果目标的activity不在栈顶,则跟standard一样创建新的实例
  3. singleTask:Task栈内复用模式
    1. **在同一个任务栈中,如果启动的activity已经在栈中,则会复用activity,**并调用onNewIntent的方法,并且该activity是上的activity会被清除,如果栈中没有,则会新建
  4. singleInstance:全局单例模式
    1. 全局复用,不管哪个Task栈,只要存在目标Activity,就复用,每个activity占有一个新的task栈

Fragment详解

  1. fragment有自己的生命周期

  2. fragment依赖于activity

  3. fragment可以通过getactivity()的方法获取所在的activity,activity通过fragmentmanager的findfragmentbyid()或findfragmentbytag获取frgment

  4. fragment与activity是多对多的关系

  5. 具体步骤

    1. 主要布局文件中一个button跳转到container文件中,在该布局中设置一个fragment布局,新建两个class和layout文件,放fragment的布局,在container的java文件中实现fragment文件的调用或者替换
  6. fragment中getactivity()为null的问题

  7. 向fragment中传入一个参数

    1. 首先不是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();
              //取消异步
          }
      
      }
  8. 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"));
        }
    }


}
  1. fragment和activity的通信
    1. 利用接口来实现数据传递

第五章

必须深刻理解的andriod事件处理

  1. 监听三要素

    1. Event Source
    2. Event
    3. Event Listener
  2. 实现监听的方法

    1. 通过内部类实现mBtnEvent.setOnClickListener(new OnClick());

    2. 通过匿名内部类实现

    3. 通过事件源所在类实现

      1. 让该类去实现接口
    4. 通过外部类实现

      1. 新建一个java文件实现onclickliatener的方法

      2. 在需要的文件中调用该方法

        //通过外部类实现
        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...");
            }
        }
    5. 布局文件中onClick属性(优先级最低)

基于回调的事件处理

  1. 回调机制和监听机制的区别

    1. 回调事件,是由控件向acticity传播
  2. 基于回调的事件传播

    1. 如果需要一层一层的传播一定是return false
    2. 如果想在那一层停止,在该层换成return true即可
  3. 注意在新建一个class文件继承某一类的时候,一定要注意把里面的方法写全,不然会炸

  4. 监听优先于回调

源码剖析,了解View的事件分发

  1. dispatchTouchEvent–>setOnTouchListener—>onTouchEvent
  2. dispatchTouchEvent相当于一个入口
  3. onClick/onLongClick来自onTouchEvent的处理

Handler消息处理

  1. 主要用途:

    1. 未来某时做某事

    2. 线程间通信

      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();
          }
      }

Author: Superior Leo
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Superior Leo !
评论
  TOC