android入门(1)

185 阅读13分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之路

  1. android studio的配置
    1. view: 位于android.view包中 View的子类位于android.widget包中
      • 属性
        1. id
        2. background
        3. padding 内边距 上下左右
    2. viewGroup 控制view如何拜访
      1. layoutParams
        1. layout_height match_pa rent 与容器相同 wrap_content与内容为主
        2. layout_width
      2. marginLayoutParams 外边距
        1. layout_marginTop
        2. layout_marginBottom
        3. layout_marginStart
        4. layout_marginEnd
  2. 布局管理器
    1. 相对布局管理器RelativeLayout
      1. 布局管理器属性
        1. gravity子组件摆放
        2. ignoregravity:[组件id] 无视
      2. 子组件属性
        1. layout_above[组件id] 组件相对于参考位置
        2. layout_alignParentBottom [bool] 组件相对于父容器
        3. layout_alingnBottom [组件id] 组件相对于参考位置的边界
        4. layout_centerHorizontal 位于布局管理器的位置
    2. 线性布局管理器LinearLayout
      1. 布局管理器的属性
        1. orientation
          1. vertical 垂直
          2. horizontal 水平
        2. gravity 显示效果 center,right|bottom
      2. 组件属性
        1. layout_weight:
    3. 帧布局管理器FrameLayout
      1. 布局管理器的属性
        1. foreground 最前端图片
        2. foregroundGravity前端图片位置
    4. 表格布局管理器TableLayout [可跨列]
      1. 布局管理器的属性
        1. TableRow 行
        2. collapseColumns 隐藏列
        3. stretchColumns 允许被拉伸
        4. shrinkColumns 允许被收缩
    5. 网格布局管理器GridLayout [可跨行列]
      1. 布局管理器的属性
        1. columnCount 列数
        2. orientation 水平或垂直排列
        3. rowCount 行数
      2. 组件属性
        1. layout_column 指定位于第几列
        2. layout_columnSpan 指定横向跨几列
        3. layout_columnWeight 水平方向权重
        4. layout_gravity 方式
        5. layout_row 指定位于第几行
        6. layout_rowSpan 指定跨几行
        7. layout_rowWeight 指定垂直方向权重
  3. 组件
    1. 文本框组件textView
      1. text [string values]
      2. textSize [sp]
      3. textColor
      4. singleLine 单行文本框
    2. 编辑框组件EditText
      1. hint 提示文本
      2. inputType 输入类型 [textMutline]
      3. drawableLeft/drawableStart/drawableEnd/drawableBottom/drawablePadding
      4. lines
      5. getText()获取编辑框内容
    3. 按钮Button
      1. Text 内容
      2. 监听器
      3. 匿名内部类
      4. xml中指定
    4. 图片按钮 ImageButton
    5. 单选框radioButton
      1. radioGroup 遍历getChildAt 获取单个radioButton
      2. radioGroup onCheckedChangeListener checkedId-->radioButton
    6. 复选框checkBox
    7. 时间dataPicker
      1. init() 初始化
      2. onDataChange 事件
    8. TimePicker时钟
    9. 计时器Chronometer
      1. setBase 设置起始时间
      2. setFormat 设置显示时间格式
      3. start 指定开始计时
      4. stop 指定停止计时
      5. onChrometerTick
    10. 进度条progressBar
      1. style
        1. style="?android:attr/progressBarStyleHorizontal"
        2. style="@android:style/Widget.ProgressBar.Horizontal
        3. style="@android:style/Widget.ProgressBar.Inverse
      2. max 最大值
      3. progress 当前值
    11. 拖动条SeekBar
    12. 星级评分条
      1. numstarts 星星总数
      2. rating 点亮个数
      3. stepSize
      4. isIndicator 是否不可更改
    13. 图像视图 ImageView
      1. scaleType
        1. center 保持图像大小 以ImageView为中心 图像大截取
        2. centerInside 原图大按照比例缩放 原图小 居中显示
        3. centerCrop 原图大按比例缩放 原图小 按宽高比例放大
        4. matrix 原图大小显示在左上角
        5. fitXy 填充
        6. fitStart 以ImageView的高度放大缩小 显示在上方
        7. fitCenter 以ImageView的高度放大缩小 显示在中间
        8. fitEnd 以ImageView的高度放大缩小 显示在下方
      2. adjustViewBounds 是否调整
      3. maxHeight
      4. maxWidth
    14. GridView视图管理器
      1. numColumn 几列
      2. columnWidth 每列宽度
      3. verticalSpace 横向空隙
      4. Adapter 适配器
        1. BaseAdapter
                      public class ImageAdapter extends BaseAdapter {
                      private Context imageContext;
          
                  public ImageAdapter(Context c) {
                          imageContext = c;
                      }
          
                      @Override
                  public int getCount() {
                          return imageResource.length;
                      }
          
                      @Override
                  public Object getItem(int position) {
                          return null;
                      }
          
                      @Override
                  public long getItemId(int position) {
                          return 0;
                      }
          
                      @Override
                      public View getView(int position, View convertView, ViewGroup parent) {
                          ImageView imageView;
                          if (convertView == null) {
                              imageView = new ImageView(imageContext);
                              imageView.setLayoutParams(new GridView.LayoutParams(300, 150));
                              imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                          } else {
                              imageView = (ImageView) convertView;
                          }
                          imageView.setImageResource(imageResource[position]);
                      return imageView;
                  }
              }
          
          
        2. SimpleAdapter
              List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
              for (int i = 0; i < imageResource.length; i++) {
                  Map<String, Object> map = new HashMap<>();
                  map.put("img", imageResource[i]);
                  list.add(map);
          }
          SimpleAdapter simpleAdapter = new SimpleAdapter(this, list, R.layout.cell, new String[]{"img"}, new int[]{R.id.image});
          gridView.setAdapter(simpleAdapter);
          
        3. ArrayAdapter
        4. SimpleCursorAdapter
    15. Spinner 下拉列表
      1. setOnItemSelectedListener 选中监听器
      2. entries 数组资源
    16. ScrollView 滚动条
      1. 向下滚动条
      2. 横向滚动条HorizontalScrollView
    17. 选项卡
      1. TabHost
      2. TabWidget
      3. TabContent
        <?xml version="1.0" encoding="utf-8"?>
        <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        android:orientation="vertical">
        
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
            android:layout_height="wrap_content"></TabWidget>
        
            <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        </LinearLayout>
        </TabHost>
        
        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/left1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
            android:gravity="center"
                android:text="Hello World"
                android:textSize="30sp" />
        </LinearLayout>
        
        package com.example.tabhost;
        
        import android.os.Bundle;
            import android.view.LayoutInflater;
        import android.widget.TabHost;
        
        import androidx.appcompat.app.AppCompatActivity;
        
            public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                TabHost tabHost = findViewById(android.R.id.tabhost);
                //初始化
                tabHost.setup();
                LayoutInflater layoutInflater = LayoutInflater.from(this);
                layoutInflater.inflate(R.layout.tab1, tabHost.getTabContentView());
                layoutInflater.inflate(R.layout.tab2, tabHost.getTabContentView());
                layoutInflater.inflate(R.layout.tab3, tabHost.getTabContentView());
                tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("测试1").setContent(R.id.left1));
                tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("测试2").setContent(R.id.right));
                tabHost.addTab(tabHost.newTabSpec("tab3").setIndicator("测试3").setContent(R.id.left3));
            }
        }
        
        
  4. activity
    1. 概述 代表手机屏幕的一屏

    2. 4种状态度

      1. 运行
      2. 暂停
      3. 停止
      4. 销毁
    3. 生命周期

      1. onCreate
      2. onStart
      3. onResume
      4. onPause
      5. onStop
      6. onDestory
      7. onRestart
    4. 创建并配置

      1. 创建类
      2. 继承Activity
      3. 重写onCreate方法
      4. setContent
    5. 启动与关闭

      1. startActivity(Intent)
      2. finish()
        package com.example.activity;
        
        import android.content.Intent;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.widget.Button;
        import android.widget.Toast;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        public class MainActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                Button button = findViewById(R.id.bt);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(MainActivity.this, "测试", Toast.LENGTH_SHORT).show();
                        Log.i("测试", "测试");
                        Intent intent = new Intent(MainActivity.this, MyActivity.class);
                        startActivity(intent);
        
                    }
                });
                Button button1 = findViewById(R.id.bt1);
                button1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        finish();
                    }
                });
        
            }
        

      } ```

    6. 多个Activity交换数据

      • 储存值

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Button button = findViewById(R.id.save);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //获取数据
                    String name = ((EditText) (findViewById(R.id.name))).getText().toString();
                    String phone = ((EditText) (findViewById(R.id.phone))).getText().toString();
                    String adress = ((EditText) (findViewById(R.id.adress))).getText().toString();
                    String deatilAdress = ((EditText) findViewById(R.id.deatilAdress)).getText().toString();
                    //验证
                    if (!"".equals(name) && !"".equals(phone) && !"".equals(adress) && !"".equals(deatilAdress)) {
                        //创建intent
                        Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                        Bundle bundle = new Bundle();
                        //储存值
                        bundle.putCharSequence("name", name);
                        bundle.putCharSequence("phone", phone);
                        bundle.putCharSequence("adress", adress);
                        bundle.putCharSequence("deatilAdress", deatilAdress);
                        intent.putExtras(bundle);
                        startActivity(intent);
                    } else {
                        Toast.makeText(MainActivity.this, "请将收货地址填写完整!!", Toast.LENGTH_SHORT).show();
            }
        
                }
            });
        }
        
        
      • 获取值

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main2);
                Bundle bundle = getIntent().getExtras();
                String name = bundle.getString("name");
                String phone = bundle.getString("phone");
                String adress = bundle.getString("adress");
                String deatilAdress = bundle.getString("deatilAdress");
                ((TextView) findViewById(R.id.name)).setText(name);
                ((TextView) findViewById(R.id.phone)).setText(phone);
                ((TextView) findViewById(R.id.adress)).setText(adress + deatilAdress);
            }
        }
        
        
    7. 切换Activity返回结果

          @Override
          protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
              super.onActivityResult(requestCode, resultCode, data);
              //返回后的操作
              if (requestCode == 0x1234 && resultCode == 0x1234) {
                  //获取数据包
                  Bundle bundle = data.getExtras();
                  int imageId = bundle.getInt("imageId");
                  //设置头像
                  ImageView imageView = findViewById(R.id.image);
                  imageView.setImageResource(imageId);
          }
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              Button button = findViewById(R.id.choose);
              button.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                      startActivityForResult(intent, 0x1234);
                  }
              });
          }
      
          private int[] imageResource = new int[]{
                  R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1, R.drawable.img1
          };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main2);
              GridView gridView = findViewById(R.id.gridView);
              List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
              for (int i = 0; i < imageResource.length; i++) {
                  Map<String, Object> map = new HashMap<>();
                  map.put("image", imageResource[i]);
                  list.add(map);
              }
              SimpleAdapter simpleAdapter = new SimpleAdapter(this, list, R.layout.model, new String[]{"image"}, new int[]{R.id.img});
              gridView.setAdapter(simpleAdapter);
              gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                      Intent intent = getIntent();
                      Bundle bundle = new Bundle();
                      bundle.putInt("imageId", imageResource[position]);
                      intent.putExtras(bundle);
                      setResult(0x1234, intent);
                      finish();
                  }
              });
          }
      
    8. Fragment

      1. 生命周期
      2. Fragment的创建
      3. 在Activity中添加Fragment
      4. 实例代码
        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">
        
            <LinearLayout
                android:id="@+id/test"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"></LinearLayout>
            <!--按钮-->
            <GridLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:columnCount="6"
                android:paddingBottom="5dp">
        
                <TextView
                    android:layout_width="20dp"
                    android:layout_height="wrap_content"
                    android:layout_column="0" />
        
                <ImageButton
                    android:id="@+id/message"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="1"
                    android:layout_columnWeight="1"
                    android:layout_marginStart="20dp"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/message" />
        
                <ImageButton
                    android:id="@+id/contact"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="2"
                    android:layout_columnWeight="1"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/contact" />
        
                <ImageButton
                    android:id="@+id/discovery"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="3"
                    android:layout_columnWeight="1"
                    android:layout_gravity="center"
                    android:background="#00FFFFFF"
                    android:src="@drawable/discovery" />
        
                <ImageButton
                    android:id="@+id/my"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_column="4"
                    android:layout_columnWeight="1"
                    android:background="#00FFFFFF"
                    android:scaleType="center"
                    android:src="@drawable/my" />
        
                <TextView
                    android:layout_width="20dp"
                    android:layout_height="wrap_content"
                    android:layout_column="5" />
            </GridLayout>
        </RelativeLayout>	
        
        package com.example.test;
        
        import android.app.Fragment;
        import android.os.Bundle;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        
        import androidx.annotation.Nullable;
        
        /** 创建Fragment */
        public class ContactFrament extends Fragment {
        @Nullable
        @Override
        public View onCreateView(
            LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.contact, container, false);
            return view;
        }
        }
        
        
        package com.example.test;
        
        import android.app.Fragment;
        import android.app.FragmentTransaction;
        import android.os.Bundle;
        import android.view.View;
        import android.widget.ImageButton;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        /** * 使用与切换Fragment */
        public class MainActivity extends AppCompatActivity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ImageButton messageButton = findViewById(R.id.message);
        
            View.OnClickListener onClickListener =
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                    Fragment f = null;
                    switch (v.getId()) {
                    case R.id.message:
                        f = new MessageFragment();
                        break;
                    case R.id.contact:
                        f = new ContactFrament();
                        break;
                    case R.id.discovery:
                        f = new DiscoveryFragment();
                        break;
                    case R.id.my:
                        f = new MyFragment();
                        break;
                    default:
                        break;
                    }
                    fragmentTransaction.replace(R.id.test, f);
                    fragmentTransaction.commit();
                }
                };
            messageButton.setOnClickListener(onClickListener);
            ImageButton contactButton = findViewById(R.id.contact);
            contactButton.setOnClickListener(onClickListener);
            findViewById(R.id.discovery).setOnClickListener(onClickListener);
            findViewById(R.id.my).setOnClickListener(onClickListener);
        }
        }
        
        
    9. Intent对象

      1. 属性

        1. Component name
        2. Action与Data
            <uses-permission android:name="android.permission.SEND_SMS" />
            <uses-permission android:name="android.permission.CALL_PHONE" />
        
            ImageButton telButton = findViewById(R.id.tel);
            ImageButton messageButton = findViewById(R.id.message);
            View.OnClickListener onClickListener =
                new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    switch (v.getId()) {
                    case R.id.tel:
                        intent.setAction(Intent.ACTION_DIAL);
                        intent.setData(Uri.parse("tel:1383838438"));
                        startActivity(intent);
                        break;
                    case R.id.message:
                        intent.setAction(Intent.ACTION_SENDTO);
                        intent.setData(Uri.parse("smsto:10086"));
                        intent.putExtra("sms_body", "测试");
                        startActivity(intent);
                    default:
                        break;
                    }
                }
                };
            telButton.setOnClickListener(onClickListener);
            messageButton.setOnClickListener(onClickListener);
        
      2. Extras属性 存放和获取数据

      3. Flag属性 FLAG_ACTIVITY_NO_HISTORY

      4. Intent种类

        1. 显示Intent
        2. 隐式Intent
  5. 事件和手势
    1. 单击事件
    2. 长按事件
      //注册事件
          findViewById(R.id.button)
              .setOnLongClickListener(
                  new View.OnLongClickListener() {
                  @Override
                  public boolean onLongClick(View v) {
                      registerForContextMenu(v);
                      openContextMenu(v);
                      return true;
                  }
                  });
      //创建菜单
      @Override
      public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
          super.onCreateContextMenu(menu, v, menuInfo);
          menu.add("收藏");
          menu.add("举报");
      }
      
    3. 物理按键事件
      //按键事件
      @Override
      public boolean onKeyDown(int keyCode, KeyEvent event) {
      //判断按键
          if (keyCode == KeyEvent.KEYCODE_BACK) {
          exit();
          return true;
          }
          return false;
      }
      //退出
      private void exit() {
          if (System.currentTimeMillis() - exitTime >= 2000) {
          Toast.makeText(MainActivity.this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();
          exitTime = System.currentTimeMillis();
          } else {
          finish();
          System.exit(0);
          }
      }
      
    4. 触摸事件
          final Hat hat = new Hat(this);
          hat.setOnTouchListener(
              new View.OnTouchListener() {
              @Override
              public boolean onTouch(View v, MotionEvent event) {
                  Toast.makeText(MainActivity.this, String.valueOf(hat.hatX), Toast.LENGTH_SHORT).show();
                  Toast.makeText(MainActivity.this, String.valueOf(event.getX()), Toast.LENGTH_SHORT)
                      .show();
                  hat.hatX = event.getX() - 310;
                  hat.hatY = event.getY() - 200;
                  hat.invalidate();
                  return true;
              }
              });
          ((FrameLayout) findViewById(R.id.frameLayout)).addView(hat);
      
      package com.jamin.event;
      
      import android.content.Context;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.Canvas;
      import android.graphics.Paint;
      import android.view.View;
      
      /**
      * @author Jamin <br>
      * @date 2019 /10/2 16:19 <br>
      * @desc 帽子 <br>
      */
      public class Hat extends View {
      public float hatX;
      public float hatY;
      
      public Hat(Context context) {
      
          super(context);
          hatX = 100;
          hatY = 100;
      }
      
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
          Paint paint = new Paint();
          Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.hat);
          canvas.drawBitmap(bitmap, hatX, hatY, paint);
          if (bitmap.isRecycled()) {
          bitmap.recycle();
          }
      }
      }
      
      
    5. 单击事件与触摸事件的区别
      1. 单击事件只触发一次
      2. 触摸事件触发两次
      3. 先触发单击事件的按下再抬起 如果返回true结束,返回false会再触发单击事件
    6. 手势检测 [查看相册的实例]
      package com.jamin.event;
      
      import android.os.Bundle;
      import android.view.GestureDetector;
      import android.view.MotionEvent;
      import android.widget.ImageView;
      import android.widget.ViewFlipper;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      public class Main2Activity extends AppCompatActivity implements GestureDetector.OnGestureListener {
          final int DISTANCE = 50;
          private int[] imageResource =
              new int[] {
              R.mipmap.img1, R.mipmap.img2, R.mipmap.img3, R.mipmap.img4, R.mipmap.img5, R.mipmap.img6
              };
          private GestureDetector detector;
          private ViewFlipper viewFlipper;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          detector = new GestureDetector(Main2Activity.this, this);
          viewFlipper = findViewById(R.id.viewFlipper);
          for (int i = 0; i < imageResource.length; i++) {
              ImageView imageView = new ImageView(Main2Activity.this);
              imageView.setImageResource(imageResource[i]);
              viewFlipper.addView(imageView);
          }
          }
      
          @Override
          public boolean onDown(MotionEvent e) {
          return false;
          }
      
          @Override
          public void onShowPress(MotionEvent e) {}
      
          @Override
          public boolean onSingleTapUp(MotionEvent e) {
          return false;
          }
      
          @Override
          public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
          return false;
          }
      
          @Override
          public void onLongPress(MotionEvent e) {}
      
          @Override
          public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
          // 向右边划
          if (e1.getX() - e2.getX() > DISTANCE) {
      
              viewFlipper.showPrevious();
              return true;
          } else if (e2.getX() - e1.getX() > DISTANCE) {
              viewFlipper.showNext();
              return true;
          }
          return false;
          }
      
          @Override
          public boolean onTouchEvent(MotionEvent event) {
          return detector.onTouchEvent(event);
          }
      }
      
      
  6. android应用的资源
    1. 字符串资源

    2. 颜色资源

    3. 尺寸资源dimans

    4. drawable资源

          <?xml version="1.0" encoding="utf-8"?>
          <selector xmlns:android="http://schemas.android.com/apk/res/android">
              <item android:color="#f60" android:state_focused="true" />
              <item android:color="#0a0" android:state_focused="false" />
          </selector>	
      
    5. mipmap资源

    6. 主题资源 Theme按钮,自定义style

    7. 菜单资源文件

      1. 选项菜单
        • 重写onCreateOptionsMenu()方法 getMenuInflater().inflate();new Intent(),startActivity()}
        • 重写onOptionsItemSelected()方法switch (item.getItemId()) {new Intent(),startActivity()}
      2. 上下文菜单
        • 重写onCreateContextMenu() getMenuInflater().inflate(R.menu.menu, menu);
        • 重写onContextItemSelected() switch(item.getItemId())
    8. android 国际化

      1. values-en-rUS
      2. values-Zh-rCN
      3. values-zh-rTW
  7. ActionBar 未完成
    1. 显示与关闭ActionBar

      1. 使用theme android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    2. ActionBar Tab

    3. 层级式导航

          //开启返回按钮
          if (NavUtils.getParentActivityName(Main2Activity.this) != null) {
          getSupportActionBar().setDisplayHomeAsUpEnabled(true);
      }
      
  8. 消息,通知
    1. 提示Toast
    2. 对话框AlertDialog
      1. 确定取消对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
                        alertDialog.setIcon(R.drawable.ic_launcher_background);
                        alertDialog.setTitle("标题");
                        alertDialog.setMessage("内容");
                        alertDialog.setButton(
                            DialogInterface.BUTTON_NEGATIVE,
                            "取消",
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(MainActivity.this, "您点击了取消按钮", Toast.LENGTH_SHORT).show();
                            }
                            });
        
                        alertDialog.setButton(
                            DialogInterface.BUTTON_POSITIVE,
                            "确定",
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(MainActivity.this, "您点击了确定按钮", Toast.LENGTH_SHORT).show();
                            }
                            });
                        alertDialog.show();
                    }
        
      2. 列表对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setIcon(R.drawable.ic_launcher_background);
                        builder.setTitle("请选择");
                        builder.setItems(
                            strings,
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + strings[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.create().show();
                    }
        
      3. 单选对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("测试");
                        builder.setSingleChoiceItems(
                            strings,
                            0,
                            new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + strings[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.setPositiveButton("确认", null);
                        builder.create().show();
                    }
        
      4. 多选对话框
                    @Override
                    public void onClick(View v) {
                        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                        builder.setTitle("测试");
                        final boolean[] booleans = new boolean[] {true, false, false, true};
                        builder.setMultiChoiceItems(
                            strings,
                            booleans,
                            new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                                Toast.makeText(
                                        MainActivity.this, "您选择的是" + booleans[which], Toast.LENGTH_SHORT)
                                    .show();
                            }
                            });
                        builder.setPositiveButton("确认", null);
                        builder.create().show();
                    }
        
    3. 通知Notification
      // 通知管理器
          NotificationManager notificationManager =
              (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
          // 通知对象
          Notification.Builder notification = new Notification.Builder(MainActivity.this);
          // 打开后自动关闭
          notification.setAutoCancel(true);
          // 标题
          notification.setContentTitle("通知标题");
          // 内容
          notification.setContentText("通知内容");
          // 图标
          notification.setSmallIcon(R.mipmap.ic_launcher);
          // 通知发送时间
          notification.setWhen(System.currentTimeMillis());
          // 设置声音和振动
          notification.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
          //    创建一个启动的Intent
          Intent intent = new Intent(MainActivity.this, Main2Activity.class);
          PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
          notification.setContentIntent(pendingIntent);
          notificationManager.notify(NOTIFYID, notification.build());
      
    4. 广播
      //  发送广播
      Intent intent = new Intent();
      intent.setAction("ceshi");
      sendBroadcast(intent);
      
      package com.jamin.boardcastreceiver;
      import android.app.AlertDialog;
      import android.content.BroadcastReceiver;
      import android.content.Context;
      import android.content.DialogInterface;
      import android.content.Intent;
      import android.view.WindowManager;
      import android.widget.Toast;
      
      /**
      * @author Jamin <br>
      * @date 2019/10/8 10:45 <br>
      * @desc 接收广播 <br>
      */
      public class Receiver extends BroadcastReceiver {
      private static final String ACTION1 = "ceshi";
      
      @Override
      public void onReceive(final Context context, Intent intent) {
      //      收到广播回复
      if (intent.getAction().equals(ACTION1)) {
      AlertDialog alertDialog = new AlertDialog.Builder(context).create();
      alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_TOAST);
      alertDialog.setIcon(R.mipmap.ic_launcher);
      alertDialog.setTitle("测试");
      alertDialog.setMessage("测试内容");
      alertDialog.setButton(
      DialogInterface.BUTTON_NEGATIVE,
      "取消",
      new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      Toast.makeText(context, "收到测试信息", Toast.LENGTH_SHORT).show();
      }
      });
      alertDialog.setButton(
      DialogInterface.BUTTON_POSITIVE,
      "确定",
      new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
      Toast.makeText(context, "收到测试信息", Toast.LENGTH_SHORT).show();
      }
      });
      alertDialog.show();
      }
      }
      }
      
    5. 设置闹钟
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final TimePicker timePicker = findViewById(R.id.timePicker);
          timePicker.setIs24HourView(true);
          findViewById(R.id.setting)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      // 创建intent对象
                      Intent intent = new Intent(MainActivity.this, AlarmActivity.class);
                      // 获取显示闹钟的pendingIntent对象
                      PendingIntent pendingIntent =
                          PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
                      // 获取AlarmManager对象
                      AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                      //                设置闹钟时间
                      Calendar calendar = Calendar.getInstance();
                      calendar.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
                      calendar.set(Calendar.MINUTE, timePicker.getCurrentMinute());
                      calendar.set(Calendar.SECOND, 0);
                      //   设置一个闹钟
                      alarmManager.set(
                          AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
                      Toast.makeText(MainActivity.this, "设置成功", Toast.LENGTH_SHORT).show();
                      }
                  });
          }
      
  9. 画图与动画
    1. 绘制矩形
      Paint paint = new Paint();
          paint.setColor(0xFFFF0000);
          paint.setAntiAlias(true);
          paint.setTextAlign(Paint.Align.LEFT);
          paint.setTextSize(30);
          canvas.drawText("测试", 105, 102, paint);
      
    2. 绘制文字
      Paint paint = new Paint();
          String path = Environment.getExternalStorageDirectory() + "/1.jpg";
          Bitmap bitmap = BitmapFactory.decodeFile(path);
          canvas.drawBitmap(bitmap, 0, 0, paint);
      
    3. 绘制图片
      Paint paint = new Paint();
          String path = Environment.getExternalStorageDirectory() + "/1.jpg";
          Bitmap bitmap = BitmapFactory.decodeFile(path);
          canvas.drawBitmap(bitmap, 0, 0, paint);
      
    4. 绘制路径
      Paint paint = new Paint();
      paint.setColor(0xFF000000);
      paint.setAntiAlias(true);
      paint.setStrokeWidth(1);
      paint.setTextSize(30);
      paint.setStyle(Paint.Style.STROKE);
      Path path = new Path();
      path.addCircle(100, 200, 60, Path.Direction.CW);
      //    canvas.drawPath(path, paint);canvas.drawPath(path, paint);
      canvas.drawTextOnPath("中华人民共和国", path, 100, 200, paint);
      
    5. 逐帧动画
          <?xml version="1.0" encoding="utf-8"?>
          <!--逐帧动画资源文件-->
          <animation-list xmlns:android="http://schemas.android.com/apk/res/android">
              <item
                  android:drawable="@mipmap/img1"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img2"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img3"
                  android:duration="60" />
              <item
                  android:drawable="@mipmap/img4"
                  android:duration="60" />
          </animation-list>
      
      <!--使用动画资源-->
          android:background="@drawable/anim"
      
    6. 补间动画
      1. 透明度渐变动画
            <?xml version="1.0" encoding="utf-8"?>
            <set xmlns:android="http://schemas.android.com/apk/res/android">
                <!-- 持续时间 完全透明到完全不透明-->
                <alpha
                    android:duration="2000"
                    android:fromAlpha="0"
                    android:toAlpha="1" />
            </set>
        
                //              使用动画资源
                Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anim4);
                imageView.startAnimation(animation);
        
    7. 旋转动画
          <?xml version="1.0" encoding="utf-8"?>
          <set xmlns:android="http://schemas.android.com/apk/res/android">
              <!--开始角度 最终角度   xy轴  持续时间-->
              <rotate
                  android:duration="2000"
                  android:fromDegrees="0"
                  android:pivotX="50%"
                  android:pivotY="50%"
                  android:toDegrees="360" />
          </set>
      
    8. 缩放动画
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
          <!--持续时间 从xy的0.5到1 中心点-->
          <scale
              android:duration="2000"
              android:fromXScale="0.5"
              android:fromYScale="0.5"
              android:pivotX="50%"
              android:pivotY="50%"
              android:toXScale="1"
              android:toYScale="1" />
      </set>
      
      
    9. 平移动画
      <?xml version="1.0" encoding="utf-8"?>
      <set xmlns:android="http://schemas.android.com/apk/res/android">
      <!--起始点到终点 持续时间-->
      <translate
      android:duration="2000"
      android:fromXDelta="0"
      android:fromYDelta="0"
      android:toXDelta="300"
      android:toYDelta="0" />
      </set>
      
  10. 音频视频
    1. 音频
      package com.example.musicvideo;
      
      import android.media.MediaPlayer;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.view.View;
      import android.widget.ImageButton;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      /**
          * @author Jamin
          * @date 2019/10/9
          * @desc 使用mediaPlayer简易播放器
          */
      public class MainActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final MediaPlayer mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.mp31);
          findViewById(R.id.start)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      //                  音频播放
                      mediaPlayer.start();
                      }
                  });
          findViewById(R.id.pause)
              .setOnClickListener(
                  new View.OnClickListener() {
                      //                音频暂停
                      @Override
                      public void onClick(View v) {
                      mediaPlayer.pause();
                      }
                  });
          findViewById(R.id.stop)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      //                  音频停止
                      mediaPlayer.pause();
                      mediaPlayer.seekTo(0);
                      }
                  });
      
          String path = Environment.getExternalStorageDirectory() + "/mp31.mp3";
          Log.i("测试", path);
          final MediaPlayer mediaPlayer1 = MediaPlayer.create(MainActivity.this, Uri.parse(path));
          final ImageButton playPause = findViewById(R.id.play);
          playPause.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  if (mediaPlayer1.isPlaying()) {
                      mediaPlayer1.pause();
                      ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  } else {
                      mediaPlayer1.start();
                      ((ImageButton) v).setImageDrawable(getResources().getDrawable(R.mipmap.pause));
                  }
                  }
              });
          ImageButton stop = findViewById(R.id.stop2);
          stop.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  mediaPlayer1.pause();
                  mediaPlayer1.seekTo(0);
                  playPause.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  }
              });
          }
      }
      
      
          ListView listView = findViewById(R.id.listView);
          // 音频属性,使用场景 音效类型
          AudioAttributes audioAttributes =
              new AudioAttributes.Builder()
                  .setUsage(AudioAttributes.USAGE_MEDIA)
                  .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                  .build();
          // 创建soundPool对象 配置相关参数
          final SoundPool soundPool =
              new SoundPool.Builder().setAudioAttributes(audioAttributes).setMaxStreams(10).build();
          //    将音频资源放入hashMap中
          final HashMap<Integer, Integer> hashMap = new HashMap<>();
          //    加载音频,优先权 值越大优先权越高
          hashMap.put(0, soundPool.load(MainActivity.this, R.raw.nomatter, 1));
          hashMap.put(1, soundPool.load(MainActivity.this, R.raw.nextofkin, 1));
          hashMap.put(2, soundPool.load(MainActivity.this, R.raw.makingmefeel, 1));
          listView.setOnItemClickListener(
              new AdapterView.OnItemClickListener() {
                  @Override
                  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                  //              资源文件,左声道音量0-1,右声道音量,优先级值越大优先级越高,循环,速率0.5-2
                  soundPool.play(hashMap.get(position), 1, 1, 0, 0, 1);
                  }
              });        
      
    • MediaPlayer与SoundPool区别
      1. MediaPlayer 延迟长,占用资源多,不支持同时播放多个音频
      2. SoundPool延迟短,占用资源少,支持多音频播放
    1. 视频

      package com.example.musicvideo;
      
      import android.media.MediaPlayer;
      import android
      .os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.widget.MediaController;
      import android.widget.Toast;
      import android.widget.VideoView;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.File;
      
      public class Main2Activity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main2);
          VideoView videoView = findViewById(R.id.videoView);
          //    控制组件
          videoView.setMediaController(new MediaController(Main2Activity.this));
          String path = Environment.getExternalStorageDirectory() + "/mp41.mp4";
          Log.i("测试", path);
          File file = new File(path);
          if (file.exists()) {
              videoView.setVideoPath(file.getAbsolutePath());
              Toast.makeText(Main2Activity.this, "文件存在", Toast.LENGTH_SHORT).show();
          } else {
              Toast.makeText(Main2Activity.this, "文件不存在", Toast.LENGTH_SHORT).show();
          }
          //    获取焦点
          videoView.requestFocus();
          videoView.start();
          //    播放完毕触发事件
          videoView.setOnCompletionListener(
              new MediaPlayer.OnCompletionListener() {
                  @Override
                  public void onCompletion(MediaPlayer mp) {
                  Toast.makeText(Main2Activity.this, "播放完毕", Toast.LENGTH_SHORT).show();
                  }
              });
          }
      }
      
      
      package com.example.musicvideo;
      
      import android.media.AudioManager;
      import android.media.MediaPlayer;
      import android.os.Bundle;
      import android.os.Environment;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.widget.ImageButton;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import java.io.IOException;
      
      /**
          * @author Jamin
          * @date 2019/10/10
          * @desc 使用mediaPlayer+surfaceView实现播放视频
          */
      public class Main3Activity extends AppCompatActivity {
          private boolean isPause = false;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main3);
          SurfaceView surfaceView = findViewById(R.id.surfaceView);
          final SurfaceHolder surfaceHolder = surfaceView.getHolder();
          final MediaPlayer mediaPlayer = new MediaPlayer();
          //    设置多媒体类型
          mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
          try {
      
              mediaPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/mp41.mp4");
              //                  预加载
              mediaPlayer.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          final ImageButton playButton = findViewById(R.id.start3);
          playButton.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  if (mediaPlayer.isPlaying()) {
                      mediaPlayer.pause();
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                  } else {
                      //                将视频输出到surfaceView
                      mediaPlayer.setDisplay(surfaceHolder);
                      mediaPlayer.start();
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.pause));
                  }
                  }
              });
      
          findViewById(R.id.stop3)
              .setOnClickListener(
                  new View.OnClickListener() {
                      @Override
                      public void onClick(View v) {
                      mediaPlayer.pause();
                      mediaPlayer.seekTo(0);
                      playButton.setImageDrawable(getResources().getDrawable(R.mipmap.start));
                      }
                  });
          }
      }
      
      
    2. 控制相机

      
      package com.example.musicvideo;
      
      import android.Manifest;
      import android.app.Activity;
      import android.content.Intent;
      import android.content.pm.ActivityInfo;
      import android.content.pm.PackageManager;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.PixelFormat;
      import android.hardware.Camera;
      import android.net.Uri;
      import android.os.Bundle;
      import android.os.Environment;
      import android.provider.MediaStore;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.view.Window;
      import android.widget.ImageButton;
      import android.widget.Toast;
      
      import androidx.core.content.ContextCompat;
      
      import java.io.File;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      /**
          * @author Jamin
          * @date 2019/10/10
          * @desc 拍照与录像
          */
      public class Main4Activity extends Activity implements SurfaceHolder.Callback {
      
          private Camera camera;
          private SurfaceView surfaceView;
          private SurfaceHolder surfaceViewHolder;
          private int cameraId = 0;
          private ImageButton takePhoto;
          private Camera.PictureCallback pictureCallback =
              new Camera.PictureCallback() {
              @Override
              public void onPictureTaken(byte[] data, Camera camera) {
                  //        根据拍照数据创建位图
                  Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                  //        停止预览
                  camera.stopPreview();
                  File dir = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/");
                  if (!dir.exists()) {
                  //            创建文件夹
                  dir.mkdir();
                  }
                  String fileName = System.currentTimeMillis() + ".jpeg";
                  File file = new File(dir, fileName);
                  try {
                  FileOutputStream fileOutputStream = new FileOutputStream(file);
                  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
                  fileOutputStream.flush();
                  fileOutputStream.close();
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  } catch (IOException e) {
                  e.printStackTrace();
                  }
                  // 将图片添加到系统图库
                  try {
                  MediaStore.Images.Media.insertImage(
                      Main4Activity.this.getContentResolver(), file.getAbsolutePath(), fileName, null);
                  } catch (FileNotFoundException e) {
                  e.printStackTrace();
                  }
                  // 通知图库更新
                  Main4Activity.this.sendBroadcast(
                      new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + "")));
                  //          保存图片
                  Toast.makeText(Main4Activity.this, "照片保存至" + file, Toast.LENGTH_SHORT).show();
                  camera.startPreview();
              }
              };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          setContentView(R.layout.activity_main4);
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
          initView();
          initButton();
          }
      
          private void initButton() {
          takePhoto = findViewById(R.id.imgbt1);
          takePhoto.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  camera.takePicture(null, null, pictureCallback);
                  }
              });
          }
      
          private void initView() {
          surfaceView = findViewById(R.id.surface);
          surfaceViewHolder = surfaceView.getHolder();
          surfaceViewHolder.addCallback(this);
          }
      
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
          if (ContextCompat.checkSelfPermission(Main4Activity.this, Manifest.permission.CAMERA)
              != PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(Main4Activity.this, "请先打开权限", Toast.LENGTH_LONG).show();
          } else {
              cameraOpen();
          }
          }
      
          private void cameraOpen() {
          try {
              //      打开相机
              camera = Camera.open(cameraId);
              //    反转
              camera.setDisplayOrientation(90);
              camera.setPreviewDisplay(surfaceViewHolder);
              camera.startPreview();
              //      自动对焦
              camera.autoFocus(null);
          } catch (IOException e) {
              e.printStackTrace();
              camera.release();
              camera = null;
              Toast.makeText(Main4Activity.this, "不能打开摄像机", Toast.LENGTH_SHORT).show();
          }
          }
      
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          //    设置参数
          Camera.Parameters parameters = camera.getParameters();
          parameters.setPictureFormat(PixelFormat.JPEG);
          parameters.set("jpeg-quality", 80);
          camera.setParameters(parameters);
          camera.startPreview();
          }
      
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
          camera.stopPreview();
          camera.release();
          camera = null;
          }
      
          @Override
          protected void onPause() {
          super.onPause();
          //    释放资源
          if (camera != null) {
              camera.stopPreview();
              camera.release();
          }
          }
      }
      
      
      package com.example.musicvideo;
      
      import android.Manifest;
      import android.content.pm.PackageManager;
      import android.hardware.Camera;
      import android.media.MediaRecorder;
      import android.os.Bundle;
      import android.os.Environment;
      import android.os.SystemClock;
      import android.util.Log;
      import android.view.SurfaceHolder;
      import android.view.SurfaceView;
      import android.view.View;
      import android.widget.Chronometer;
      import android.widget.ImageButton;
      import android.widget.Toast;
      
      import androidx.appcompat.app.AppCompatActivity;
      import androidx.core.content.ContextCompat;
      
      import java.io.File;
      import java.io.IOException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.List;
      
      /**
          * @author Jamin
          * @date 2019/10/11
          * @desc 视频录制
          */
      public class Main5Activity extends AppCompatActivity implements SurfaceHolder.Callback {
          private File videoFile;
          private MediaRecorder mediaRecorder;
          private Camera camera;
          private SurfaceView surfaceView;
          private SurfaceHolder surfaceHolder;
          private int cameraId = 0;
          private Camera.Parameters parameters;
          private Chronometer chronometer;
          private ImageButton stopVideo;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main5);
          surfaceView = findViewById(R.id.surface2);
          surfaceHolder = surfaceView.getHolder();
          surfaceHolder.addCallback(this);
          chronometer = findViewById(R.id.chronometer);
          final ImageButton videoButton = findViewById(R.id.imgbt2);
          videoButton.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
      
                  record();
                  // 开始录像后开始按钮不可点击
                  videoButton.setEnabled(false);
                  //            停止按钮可点击
                  stopVideo.setEnabled(true);
                  }
              });
          stopVideo = findViewById(R.id.imgbt3);
          // 设置停止按钮不可点击
          stopVideo.setEnabled(false);
          stopVideo.setOnClickListener(
              new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
                  mediaRecorder.stop();
                  chronometer.stop();
                  chronometer.setBase(SystemClock.elapsedRealtime());
                  Toast.makeText(
                          Main5Activity.this, "视频保存至" + videoFile.getAbsolutePath(), Toast.LENGTH_SHORT)
                      .show();
                  //            录像结束后开始按钮可点击
                  videoButton.setEnabled(true);
                  stopVideo.setEnabled(false);
                  }
              });
          }
      
          @Override
          protected void onResume() {
          super.onResume();
          camera = Camera.open();
          }
      
          @Override
          protected void onPause() {
          super.onPause();
          camera.stopPreview();
          camera.release();
          }
      
          /** 开始录制 */
          private void record() {
          settingMediaRecorder();
          //    准备录像
          try {
              mediaRecorder.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }
      
          //    开始录像
          mediaRecorder.start();
          chronometer.setBase(SystemClock.elapsedRealtime());
          chronometer.start();
          }
      
          /** 录像配置 */
          public void settingMediaRecorder() {
          File path = new File(Environment.getExternalStorageDirectory() + "/MyVideo");
          if (!path.exists()) {
              path.mkdir();
          }
          SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
          String fileName = simpleDateFormat.format(new Date()) + ".mp4";
          videoFile = new File(path, fileName);
          mediaRecorder = new MediaRecorder();
          //    camera.setDisplayOrientation(90);
          //    解锁相机
          camera.unlock();
          //    使用相机
          mediaRecorder.setCamera(camera);
          mediaRecorder.reset();
          //    使用麦克风和相机获取视频音频
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
          //    输出格式
          mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
          //    编码格式
          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
          mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
          //   设置比特率
          mediaRecorder.setVideoEncodingBitRate(1080 * 1920);
          //    设置分辨率
          List<Camera.Size> supportedVideoSizes = parameters.getSupportedVideoSizes();
          for (Camera.Size size : supportedVideoSizes) {
              if (size.width / 16 == size.height / 9) {
      
              mediaRecorder.setVideoSize(size.width, size.height);
      
              Log.d("setPictureSize", "SET width:" + size.width + " height " + size.height);
      
              break;
              }
          }
      
          // 设置帧率
          mediaRecorder.setVideoFrameRate(24);
          // 输出路径
          mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
          // 预览
          mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
          //    调整角度
          mediaRecorder.setOrientationHint(90);
          }
      
          /**
          * 权限检测
          *
          * @param holder
          */
          @Override
          public void surfaceCreated(SurfaceHolder holder) {
          if (ContextCompat.checkSelfPermission(Main5Activity.this, Manifest.permission.CAMERA)
                  != PackageManager.PERMISSION_GRANTED
              && ContextCompat.checkSelfPermission(Main5Activity.this, Manifest.permission.RECORD_AUDIO)
                  != PackageManager.PERMISSION_GRANTED) {
              Toast.makeText(Main5Activity.this, "请先打开权限", Toast.LENGTH_LONG).show();
          } else {
              cameraOpen();
          }
          }
      
          /** 打开相机 */
          private void cameraOpen() {
          try {
              //      打开相机
              camera = Camera.open(cameraId);
              //    反转
              camera.setDisplayOrientation(90);
              camera.setPreviewDisplay(surfaceHolder);
              camera.startPreview();
          } catch (IOException e) {
              e.printStackTrace();
              camera.release();
              camera = null;
              Toast.makeText(Main5Activity.this, "不能打开摄像机", Toast.LENGTH_SHORT).show();
          }
          }
      
          /**
          * 设置相机参数
          *
          * @param holder
          * @param format
          * @param width
          * @param height
          */
          @Override
          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
          parameters = camera.getParameters();
          parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
          camera.setParameters(parameters);
          camera.startPreview();
          }
      
          /**
          * 销毁操作
          *
          * @param holder
          */
          @Override
          public void surfaceDestroyed(SurfaceHolder holder) {
          if (camera != null) {
              camera.release();
              camera = null;
          }
          }
      }