美文网首页
Android开发第一天

Android开发第一天

作者: toro宇 | 来源:发表于2020-01-20 17:38 被阅读0次

图标平台

阿里图标库

Android学习论坛

Android巴士
AndroidDevelopers

AndroidManifest.xml
应用中所有的Activity 都需要在 这个xml文件中注册下,才能使用。

     // 启动的Activity
    <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

布局管理器

线性布局(LinearLayout)

android:gravity="center_vertical"> -- 内部 所有元素的对齐方式
android:layout_gravity="center_vertical"> -- 自己相对于 父组件的对齐方式
android:layout_weight="1"/> -- layout_weight 权重,将父组件剩余的部分按照权重比例分配

              // LinearLayout 也是控件(组件) 他的作用是做布局的
<LinearLayout
    android:id="@+id/ll_1"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:orientation="vertical"
    android:background="#000000"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="50dp"
    android:paddingBottom="10dp">

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FF0033"/>
    <!--<view-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="match_parent"-->
        <!--android:background="#FF0033"/>-->

</LinearLayout>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:orientation="horizontal"
    android:background="#0066FF"
    android:layout_marginTop="20dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"

    android:gravity="center_vertical">  <!--内部元素的对齐方式 -->
    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#fffff1"
        android:layout_weight="1"/>   <!-- layout_weight 权重,将父组件剩余的部分按照权重比例分配 -->
    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#0000df"
        android:layout_weight="2"/>
    <View
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:background="#0fd0df"
        android:layout_weight="1"/>
</LinearLayout>

相对布局(RelativeLayout)

android:layout_alignParentBottom="true" -- 相对父控件的底部对齐
android:layout_toRightOf="@id/view_1" -- 相对于某个控件的右边开始定位
android:layout_below="@id/view_1" -- 相对于某个控件的下边开始定位

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<View
    android:id="@+id/view_1"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="#133321"/>
    <!--android:layout_alignParentBottom="true"-->
<View
    android:id="@+id/view_2"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="#fae444"
    android:layout_below="@id/view_1"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:layout_below="@id/view_2"
    android:background="#999ddd"
    android:padding="15dp">
    <View
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:background="#FF0033"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:padding="15dp">
        <View
            android:id="@+id/view_3"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:background="#FF9900"/>

        <View android:id="@+id/view_4"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:background="#FF9900"
            android:layout_toRightOf="@id/view_3"
            android:layout_marginLeft="10dp"/>
    </RelativeLayout>
</LinearLayout>

</RelativeLayout>

TextView

> 获取xib元素对象

 textViewBtn = findViewById(R.id.btn_textview);

> 视图跳转

textViewBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 挑战到TextView演示界面
                Intent in = new Intent(MainActivity.this, TextViewActivity.class);
                startActivity(in);

            }
        });

> 文字大小、颜色

android:textColor="#000000"
android:textSize="16sp"

> 显示不下使用...

如果高度设置为 wrap_content。 maxLines没有设置的话,宽度显示不下会自动换行。

 android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:maxLines="1"
        android:text="哥在奔跑"
        android:ellipsize="end"  // ...
        android:textSize="24sp"

> 文字+icon

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="筛选"
        android:drawableRight="@drawable/icon_logo"
        android:drawablePadding="5dp"
        />

> 中划线、下划线

textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG); // 中划线
textView.getPaint().setAntiAlias(true); // 去除锯齿

textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);// 下划线

> 跑马灯

xml布局不生效

       android:singleLine="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"
        android:focusable="true"
        android:focusableInTouchMode="true"

代码动态布局生效

        t5 = findViewById(R.id.tv_5);
        t5.setSingleLine(true);
        t5.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        t5.setFocusable(true);
        t5.setFocusableInTouchMode(true);
        t5.setSelected(true);
        t5.setMarqueeRepeatLimit(3);

Button

继承自TextView
> 自定义背景形状

按钮等的除了文字和事件。 一般都会有通用的背景形状。 通过自定义shape来处理(在drawable源文件里选择创建shape)。

// 创建一个有圆角,有边框,有背景色的 背景形状
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
     <solid android:color="#F29900"/> <!--填充颜色-->
     <stroke android:color="#FF8812" android:width="1dp"/> <!--描边-->
     <corners android:radius="10dp"/> <!--设置圆角-->
</shape>

// 给图形添加背景形状
<Button android:background="@drawable/bg_btn1"/>

>自定义按压效果

在drawable源文件里选择创建selector ,在不同的状态下,自定义不同的shape

 <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <solid android:color="#CC7A00"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
    <item android:state_pressed="false">
        <shape>
            <solid android:color="#FF9900"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
</selector>

// 给图形添加背景形状
android:background="@drawable/bg_btn2"

>点击事件
第一种方式(不常用)

 <Button android:onClick="showToast"/>

  public  void showToast(View view){
        Toast.makeText(this,"btn被点击了",Toast.LENGTH_SHORT).show();
    }

第二种方式

 btn = findViewById(R.id.btn_three);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(ButtonActivity.this,"btn被点击了",Toast.LENGTH_SHORT).show();
            }
        });

界面的跳转

     Intent in = new Intent(MainActivity.this, TextViewActivity.class);
     startActivity(in);

EditText

登录界面案例

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".EditTextActivity"
    android:padding="15dp">

    <EditText
        android:id="@+id/et_1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:textSize="16sp"
        android:textColor="#E6E61A"
        //android:hint="手机号"
       // android:inputType="number" //限制输入为数字
       android:hint="用户名"
        android:background="@drawable/edit_one"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:drawableLeft="@drawable/name"
        android:drawablePadding="10dp"

        />
    <EditText
        android:id="@+id/et_2"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:textSize="16sp"
        android:textColor="#E6E61A"
        android:hint="密码"
        android:inputType="textPassword" // 密文
        android:layout_below="@+id/et_1"
        android:layout_marginTop="20dp"
       android:background="@drawable/edit_one"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:drawableLeft="@drawable/password"
        android:drawablePadding="10dp"
      />
</RelativeLayout>

添加背景形状 -- edit_one.xml

     <shape xmlns:android="http://schemas.android.com/apk/res/android">
   <stroke android:color="#C4C4C4" android:width="1dp"/> <!--描边-->
   <corners android:radius="10dp"/> <!--设置圆角-->
   </shape>
      public class EditTextActivity extends AppCompatActivity {
    private Button loginBtn;
    private EditText nameTF;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_text);


        loginBtn = (Button)findViewById(R.id.login_btn);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println(111);

                Toast.makeText(EditTextActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
            }
        });
        nameTF = (EditText)findViewById(R.id.et_1);
        nameTF.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                Log.d("输入字符串:",s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }
}

添加图标

创建drawable--xxhdpi文件夹 。 drawable文件存放xml文件


自定义Button事件监听器

Button事件的传递 通过 实现监听接口OnClickListener的委托对象来实现。 我们可以自定义一个实现监听接口OnClickListener的对象来 统一处理监听。

      public class MainActivity extends AppCompatActivity {

    private Button textViewBtn;
    private Button mbtn;
    private Button btn3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textViewBtn = findViewById(R.id.btn_textview);
        mbtn = findViewById(R.id.btn_2);
        btn3 = findViewById(R.id.btn3);
        setListeners();

    }
    private  void setListeners(){
        OnClick onClick = new  OnClick();
        textViewBtn.setOnClickListener(onClick);
        mbtn.setOnClickListener(onClick);
        btn3.setOnClickListener(onClick);

    }
    // 实现点击回调的接口 用来做委托代理对象
    private class OnClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent = null;
            switch (v.getId()){
                //挑战到TextView演示界面
                case R.id.btn_textview:
                    intent = new Intent(MainActivity.this, TextViewActivity.class);
                break;
                case  R.id.btn_2:
                    intent = new Intent(MainActivity.this, ButtonActivity.class);
                break;
                case  R.id.btn3:
                    intent = new Intent(MainActivity.this,EditTextActivity.class);
                break;
            }
            startActivity(intent);
        }

    }
}

RadioButton

单个选择器

自定义选中非选择背景形状 -- bg_radio_btn.xml

    <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true">
         <shape>
             <corners android:radius="5dp"/>
             <!--填充-->
             <solid android:color="#CC7A00"/>

         </shape>
    </item>
  <item android:state_checked="false">
      <shape>
          <!--圆角-->
          <corners android:radius="5dp"/>
          <!--描边-->
          <stroke android:color="#FF8812" android:width="1dp"/>
      </shape>
  </item>
</selector>

定义 选择UI

image.png
    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".RadioButtonActivity"
  android:padding="15dp">
  <RadioGroup
      android:id="@+id/gr_1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="vertical">
      <RadioButton
          android:id="@+id/rb_1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="男"
          android:checked="true"
          android:textSize="18sp"
          android:textColor="#E7A0AE"
          />
      <RadioButton
          android:id="@+id/rb_2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"

          android:text="女"
          android:textColor="#E7A0AE"/>
  </RadioGroup>
  <!--自定义选择形状-->
  <RadioGroup
      android:id="@+id/gr_2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:layout_below="@+id/gr_1"
      android:layout_marginTop="30dp">

      <RadioButton
          android:id="@+id/rd_3"
          android:layout_width="60dp"
          android:layout_height="30dp"
          android:button="@null"
          android:text="男"
          android:textSize="18sp"
          android:checked="true"
          android:gravity="center"
          android:background="@drawable/bg_radio_btn"

      />

      <RadioButton
          android:id="@+id/rd_4"
          android:layout_width="60dp"
          android:layout_height="30dp"
          android:gravity="center"
          android:button="@null"
          android:text="女"
          android:textSize="18sp"
          android:layout_marginLeft="20dp"
      android:background="@drawable/bg_radio_btn"

      />
      
  </RadioGroup>

</RelativeLayout>

事件监听

    public class RadioButtonActivity extends AppCompatActivity {
    private RadioGroup mRg1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_radio_button);

        mRg1 = (RadioGroup)findViewById(R.id.gr_1);
        mRg1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RadioButton btn = (RadioButton)findViewById(checkedId);
                Toast.makeText(RadioButtonActivity.this,btn.getText(),Toast.LENGTH_SHORT).show();
            }
        });

    }
}

复选框CheckBox

多选


    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CheckBoxActivity"
    android:padding="15dp">

    <TextView
        android:id="@+id/title1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="你会哪几种开发语言"
        android:textSize="20sp"
        android:layout_marginBottom="10dp"/>
    <CheckBox
        android:id="@+id/ck_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Android"
        android:textSize="20sp"
        android:layout_below="@+id/title1"/>

    <CheckBox
        android:id="@+id/ck_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="iOS"
        android:textSize="20sp"
        android:layout_below="@+id/ck_1"/>
    <CheckBox
        android:id="@+id/ck_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="H5"
        android:textSize="20sp"
        android:layout_below="@+id/ck_2"/>
    />
    <CheckBox
        android:id="@+id/ck_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="其他"
        android:textSize="20sp"
        android:layout_below="@+id/ck_3"/>
    />

</RelativeLayout>

自定义按钮的样式

  <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/checked"/>
<item android:state_checked="false" android:drawable="@drawable/nochecked"/>
</selector>

//使用该样式
<CheckBox
        android:id="@+id/ck_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:button="@drawable/check_box_btn"
        android:text="其他"
        android:textSize="20sp"
        android:layout_below="@+id/ck_3"/>
    />

事件处理

    public class CheckBoxActivity extends AppCompatActivity {
    private CheckBox check3,check4;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_check_box);
        check3 = (CheckBox) findViewById(R.id.ck_3);
        check4 = (CheckBox) findViewById(R.id.ck_4);
        check3.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Toast.makeText(CheckBoxActivity.this,isChecked? "3被选中" : "3取消选择",Toast.LENGTH_SHORT).show();
            }
        });
        check4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                Toast.makeText(CheckBoxActivity.this,isChecked? "4被选中" : "4取消选择",Toast.LENGTH_SHORT).show();

            }
        });
    }
}

ImageView

scaleType

fitXY: 撑满控件,宽高比可能发生改变
fitCenter: 保持宽高比缩放,直至能够完全显示
centerCrop: 保持宽高比缩放,直至完全覆盖控件,裁减显示

网络图片的加载
Glide是一个快速高效的Android图片加载库

class java.lang.SecurityException: Permission denied (missing INTERNET permission? 加载网络图片 要配置权限
在AndroidManifest.xml 中配置

      <uses-permission android:name="android.permission.INTERNET"/>

列表视图 ListView

获取xml布局的view
LayoutInflater mLayoutInflater = LayoutInflater.from(context) // 得到布局管理器 context 可以是activity

View convertView = mLayoutInflater.inflate(R.layout.list_item,null); //// 布局管理器 获取view

创建Activity 及对应的xml

    public class ListViewActivity extends Activity  {
    private ListView listView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);
        listView = (ListView)findViewById(R.id.listview);
        listView.setAdapter(new MyListAdapter(ListViewActivity.this));
        //点击事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(ListViewActivity.this,"post" + position,Toast.LENGTH_SHORT).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">
<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:divider="@null"
    ></ListView>
</LinearLayout>

适配用来做布局的代理

    public class MyListAdapter extends BaseAdapter { // 适配器,用来做布局视图的代理

    private  Context mContent;
    private LayoutInflater mLayoutInflater;
    public MyListAdapter(Context context){
        this.mContent = context;
        mLayoutInflater = LayoutInflater.from(context); // 得到布局管理器
    }
    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    // 内部函数 作用用来 指向所对应的布局,然后快捷调用处理
    static class ViewHolder{
        public ImageView imageView;
        public TextView tvTitle,tvTime,tvContent;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if (convertView == null){
            convertView = mLayoutInflater.inflate(R.layout.list_item,null); //// 布局管理器 获取view
            holder = new ViewHolder();
            holder.imageView = convertView.findViewById(R.id.imgView);
            holder.tvTitle = convertView.findViewById(R.id.text1);
            holder.tvTime = convertView.findViewById(R.id.text2);
            holder.tvContent = convertView.findViewById(R.id.text3);
            convertView.setTag(holder);

        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvTitle.setText("星空Tivoli");
        holder.tvTime.setText("2010-23-23");
        holder.tvContent.setText("测试得am的");
        Glide.with(mContent).load("https://www.baidu.com/img/bd_logo1.png?where=super").into(holder.imageView);
        return convertView;
    }
  }

自定义listItem 内容

      ?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="15dp">
    <ImageView
        android:id="@+id/imgView"
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:src="@drawable/baijing"
        android:scaleType="centerCrop"
        />
    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/imgView"
        android:layout_alignTop="@+id/imgView"
        android:layout_marginLeft="15dp"
        android:text="oneTex"
        android:textColor="@color/colorBlack"
        android:textSize="18sp"/>
    <TextView
        android:id="@+id/text2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/imgView"
        android:layout_marginLeft="15dp"
        android:layout_below="@+id/text1"
        android:layout_marginTop="15dp"
        android:textSize="17dp"
        android:textColor="@color/colorOrange"
        android:text="twoText"/>
    <TextView
        android:id="@+id/text3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/imgView"
        android:layout_marginLeft="15dp"
        android:layout_below="@+id/text2"
        android:layout_marginTop="15dp"
        android:textSize="17dp"
        android:textColor="@color/colorPink"
        android:text="twoText"/>



</RelativeLayout>

网格视图GrideView

与ListView用法一致

滚动视图ScrollView

垂直滚动:ScrollView
水平滚动:HorizontalScrollView

RecyclerView

RecyclerView 能够灵活的实现大数据集的展示,视图的管理比ListView 要更好,能够显示列表、网格、瀑布流等形式,且不同的VIewHolder能实现item多元化的功能。

》通过不同的布局管理对象来实现不同的形式,

 recyclerView.setLayoutManager(new LinearLayoutManager(LinearCyclerViewActivity.this)); //列表
GridLayoutManager// 网格
StaggeredGridLayoutManager //瀑布流

xml:

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <androidx.recyclerview.widget.RecyclerView
      android:id="@+id/recyclerview1"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/colorOrange"></androidx.recyclerview.widget.RecyclerView>

</RelativeLayout>

activity:

     public class LinearCyclerViewActivity extends AppCompatActivity {
 private RecyclerView recyclerView;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_linear_cycler_view);
     recyclerView = findViewById(R.id.recyclerview1);
     recyclerView.setLayoutManager(new LinearLayoutManager(LinearCyclerViewActivity.this));
    // manager.setOrientation(RecyclerView.HORIZONTAL); 可以设置横向滑动

     recyclerView.addItemDecoration(new Mydecoration());
     recyclerView.setAdapter(new LinearCyclerAdapter(LinearCyclerViewActivity.this, new LinearCyclerAdapter.OnClickItemListener(){

                 @Override
                 public void onClick(int position) {
                     Toast.makeText(LinearCyclerViewActivity.this,"position:" + position,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);
         outRect.set(0,0,0,getResources().getDimensionPixelOffset(R.dimen.dividerHeight));

     }
 }
 
}

adapter:


        package com.example.hellodemo.recyclerView;

import android.content.Context;
import android.content.IntentFilter;
import android.util.Log;
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.hellodemo.R;

public class LinearCyclerAdapter extends RecyclerView.Adapter<LinearCyclerAdapter.LinearViewHoler> {
    private Context context;
    private OnClickItemListener listener;
    public  LinearCyclerAdapter(Context context,OnClickItemListener listener){
        this.context  = context;
        this.listener = listener;
    }
    @NonNull
    @Override
    public LinearCyclerAdapter.LinearViewHoler onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        return new LinearViewHoler(LayoutInflater.from(context).inflate(R.layout.layout_linear_item,parent,false));
    }

    @Override
    public void onBindViewHolder(@NonNull LinearCyclerAdapter.LinearViewHoler holder, final int position) {
        holder.textView.setText("可口可乐");
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onClick(position);
            }
        });

    }

    @Override
    public int getItemCount() {
        return 20;
    }

    class LinearViewHoler extends RecyclerView.ViewHolder{
        private TextView textView;
        public  LinearViewHoler(View itemView) {
            super(itemView);
            textView =  itemView.findViewById(R.id.linear_lab);
        }
    }

    public interface  OnClickItemListener{
         void onClick(int position);
    }
}

RecyclerView 实现Gride

     griderecycleView = findViewById(R.id.grideCycle1);
        griderecycleView.setLayoutManager(new GridLayoutManager(GrideRecyclerViewActivity.this,3));
        griderecycleView.setAdapter(new GrideCyclerViewAdapter(GrideRecyclerViewActivity.this, new GrideCyclerViewAdapter.ItemClick() {
            @Override
            public void onClick(int position) {
                Toast.makeText(GrideRecyclerViewActivity.this,"positon:" + position,Toast.LENGTH_SHORT).show();
            }
        }));

RecyclerView实现瀑布流

        puRecyclerView = findViewById(R.id.puRecyclerView);
        puRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, RecyclerView.VERTICAL));
        puRecyclerView.setAdapter(new PuRecyclerViewAdapter(PuRecyclerViewActivity.this, new PuRecyclerViewAdapter.ItemOnClick() {
            @Override
            public void onClick(int position) {
                Toast.makeText(PuRecyclerViewActivity.this,"position:" + position,Toast.LENGTH_SHORT).show();
            }
        }))

不同的ViewHolder

      public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 0){
            return new LinearViewHoler(LayoutInflater.from(context).inflate(R.layout.layout_linear_item,parent,false));

        }{
            return new LinearViewHoler2(LayoutInflater.from(context).inflate(R.layout.layout_linear_item2,parent,false));
        }

    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        int type = getItemViewType(position);
        if (type == 0){

            ((LinearViewHoler)holder).textView.setText("可口可乐");

            
        }else {
            ((LinearViewHoler2)holder).textView.setText("第二种样式");
            Glide.with(context).load("https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=294893614,3986146911&fm=26&gp=0.jpg").into(((LinearViewHoler2)holder).imageView);
        }

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onClick(position);
            }
        });


    }

    @Override
    public int getItemCount() {
        return 20;
    }

    // 有多种cell类型 实现该方法 返回几种类型
    @Override
    public int getItemViewType(int position) {
        if (position % 2 == 0){
            return  0;
        }else {
            return  1;
        }

    }

    class LinearViewHoler extends RecyclerView.ViewHolder{
        private TextView textView;
        public  LinearViewHoler(View itemView) {
            super(itemView);
            textView =  itemView.findViewById(R.id.linear_lab);
        }
    }

    class LinearViewHoler2 extends RecyclerView.ViewHolder{
        private TextView textView;
        private ImageView imageView;
        public  LinearViewHoler2(View itemView) {
            super(itemView);
            textView =  itemView.findViewById(R.id.linear_lab);
            imageView = itemView.findViewById(R.id.linear_img);
        }
    }

XRecyclerView: addHeadView, addFootView 上拉加载,下拉加载

WebView

加载网页

》加载URL(网络或者本地assets文件下的html文件)
**assets下的文件不会被编译,通过本地的资源方式访问, drawable里的文件会被编译,通过对应得id访问该资源

     webview.loadUrl("网址") // 加载网络URL
     webview.loadUrl("file://android_asset/text.html") // 加载assets下的html
image.png
   public class WebViewActivity extends AppCompatActivity {
 private WebView webView;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_web_view);
     webView = findViewById(R.id.webView1);
     webView.loadUrl("file:///android_asset/test.html");
 }
}

编译,通过相应的id访问**

》加载html代码

  webview.loadData(); 或 webview.loadDataWithBaseURL();

》Native和JavaScript互相调用

网页的前后和后退

    webview.canGoBack() // 是否可以后退
    webview.goBack()
     webview.canGoForward() // 是否可以前进
     webview.GoForward()
     webview.canGoBackOrForward(int steps) // 是否可以前进或者后退 几步
     webview.GoBackOrForward(int steps)

按下返回键,默认是退出当前Activity,如果是希望Webview页面内后退,则需要重新按键触发的方法,自定义事件

     @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == keyCode.KEYCODE_BACK) && webView.canBack()){
            webView.goBack();
            return  true;
        }
        return super.onKeyDown(keyCode, event);
    }

案例

      public class WebViewActivity extends AppCompatActivity {
    private WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);
        webView = findViewById(R.id.webView1);
        // 加载本地HTML
//        webView.loadUrl("file:///android_asset/test.html");
        //加载网络URL
        webView.getSettings().setJavaScriptEnabled(true); // 如果加载的网页支持js ,要打开web的支持,否则加载不出来。默认不支持JS
        webView.loadUrl("https://www.baidu.com");

        webView.setWebViewClient(new MyWebViewClient()); // webView的控制Client代理
        webView.setWebChromeClient(new MyWebChromeClient());

        //webView.addJavascriptInterface();// js调用本地的代码

    }

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

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

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            Log.d("WebView","onPageFinished...");
//            webView.loadUrl("javascript:alert('hello')");
            webView.evaluateJavascript("javascript:alert('hello')",null);
        }

    }

    class MyWebChromeClient extends WebChromeClient {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
            setTitle(title);
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()){
            webView.goBack();
            return true;
        }
        return  super.onKeyDown(keyCode,event);

    }
}

UI弹出组件

Toast

Toast 是一个消息提示组件
设置显示的位置
自定义显示的内容(示例: 添加一张图片)

xml

      <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center">
    <LinearLayout
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/colorOrange"
        android:orientation="vertical"
        android:gravity="center">
        <ImageView
            android:id="@+id/toast_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/toast_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20sp" />

    </LinearLayout>

</LinearLayout>

activity

      public class ToastActivity extends AppCompatActivity {
    private Button btnToast1,btnToast2,btnToast3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_toast);
        btnToast1 = findViewById(R.id.btn_toast_1);
        btnToast2 = findViewById(R.id.btn_toast_2);
        btnToast3 = findViewById(R.id.btn_toast_3);
        addListers();

    }
    public void addListers(){
        MyOnClickListener listener = new  MyOnClickListener();
        btnToast1.setOnClickListener(listener);
        btnToast2.setOnClickListener(listener);
        btnToast3.setOnClickListener(listener);

    }

    class  MyOnClickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            Intent intent = null;
            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 centerToast = Toast.makeText(getApplicationContext(), "居中Toast", Toast.LENGTH_SHORT);
                    centerToast.setGravity(Gravity.CENTER, 0, 0);
                    centerToast.show();
                    break;
                case R.id.btn_toast_3:
                    Toast customToast = new Toast(getApplicationContext());
                    customToast.setGravity(Gravity.CENTER, 0, 0);
                    LayoutInflater inflater = LayoutInflater.from(ToastActivity.this);
                    View view = inflater.inflate(R.layout.toast_custom, null);
                    ImageView img = view.findViewById(R.id.toast_img);
                    TextView textview = view.findViewById(R.id.toast_title);
                    img.setImageResource(R.drawable.icon_logo);
                    textview.setText("自定义Toast");
                    customToast.setView(view);
                    customToast.setDuration(Toast.LENGTH_LONG);
                    customToast.show();

                    break;
            }

        }
    }


}

AlertDialog

activity

    public class AlertDialogActivity<UIButton> extends AppCompatActivity {
    private Button typeBtn1, typeBtn2, typeBtn3,typeBtn4, typeBtn5;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alertdialog);
        typeBtn1 = findViewById(R.id.alertdialog_type1);
        typeBtn2 = findViewById(R.id.alertdialog_type2);
        typeBtn3 = findViewById(R.id.alertdialog_type3);
        typeBtn4 = findViewById(R.id.alertdialog_type4);
        typeBtn5 = findViewById(R.id.alertdialog_type5);

        View.OnClickListener listener = new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                switch (v.getId()){

                    case R.id.alertdialog_type1: // 默认提示确认框 通过 Builder模式构建
                        AlertDialog.Builder builder = new AlertDialog.Builder(AlertDialogActivity.this);
                        builder.setTitle("温馨提示:")
                                .setIcon(R.drawable.name)
                                .setMessage("最新股票动荡,投资需谨慎")
                                .setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
                                                                @Override
                                                                public void onClick(DialogInterface dialog, int which) {

                                                                }
                                                            })
                                .setNeutralButton("再看看", new DialogInterface.OnClickListener() {
                                                                   @Override
                                                                   public void onClick(DialogInterface dialog, int which) {

                                                                 }
                                                            })
                                .setPositiveButton("没事,搞起", new DialogInterface.OnClickListener() {
                                                                @Override
                                                                public void onClick(DialogInterface dialog, int which) {

                                                                }
                                                            }).show();

                        break;
                    case R.id.alertdialog_type2: //  单选列表
                        AlertDialog.Builder builder1 = new AlertDialog.Builder(AlertDialogActivity.this);

                        final String[] ary = new  String[]{"男","女"};
                        builder1.setTitle("请选择性别").setItems(ary, new DialogInterface.OnClickListener() {


                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Toast.makeText(AlertDialogActivity.this, ary[which], Toast.LENGTH_SHORT).show();
                            }
                        }).show();


                        break;
                    case R.id.alertdialog_type3: //默认 单选框
                    final AlertDialog.Builder builder2 =  new AlertDialog.Builder(AlertDialogActivity.this);
                    final String[] ary3 = new String[]{"男","女"};
                    builder2.setTitle("选择性别:").setSingleChoiceItems(ary3,0, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Toast.makeText(AlertDialogActivity.this, ary3[which], Toast.LENGTH_SHORT).show();
                            dialog.dismiss();

                        }
                    }).setCancelable(false).show();
                        break;
                    case R.id.alertdialog_type4: // 默认多选框
                        AlertDialog.Builder builder4 = new AlertDialog.Builder(AlertDialogActivity.this);
                      final  String[] ary4 = new String[]{"打球","看书","看电影"};
                              boolean[] b = new boolean[]{false,false,false};
                        builder4.setTitle("选择兴趣:").setMultiChoiceItems(ary4, b, new DialogInterface.OnMultiChoiceClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                                Toast.makeText(AlertDialogActivity.this, ary4[which] + ":" + isChecked, Toast.LENGTH_SHORT).show();

                            }
                        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        }).show();
                        break;
                    case R.id.alertdialog_type5: // 自定义
                        View view = LayoutInflater.from(AlertDialogActivity.this).inflate(R.layout.login_alert,null); // 获取xml布局对象
                        EditText ed1 = view.findViewById(R.id.ed_name);
                        EditText ed2 = view.findViewById(R.id.ed_password);
                        Button btn = view.findViewById(R.id.login_btn2);
                        btn.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                            }
                        });

                        AlertDialog.Builder builder5 = new AlertDialog.Builder(AlertDialogActivity.this);
                        builder5.setTitle("登录:").setView(view).show();


                        break;

                }
            }
        };

        typeBtn1.setOnClickListener(listener);
        typeBtn2.setOnClickListener(listener);
        typeBtn3.setOnClickListener(listener);
        typeBtn4.setOnClickListener(listener);
        typeBtn5.setOnClickListener(listener);

    }


}

login_alert_xml

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp">
    <EditText
        android:id="@+id/ed_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="用户名"

        />
    <EditText
        android:id="@+id/ed_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        android:layout_marginTop="15dp"/>
    <Button
        android:id="@+id/login_btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="登录"
        android:layout_marginTop="20dp"/>

</LinearLayout>

ProgressDialog

activity

      public class ProgressActivity extends AppCompatActivity {
    private ProgressBar progress3;
    private Button progressBtn, progressDialogBtn1,progressDialogBtn2;
    /**
     *      定义一个按钮 点击实现 从 0 到100 进度加载的过程
     * */

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress);
        progress3 = findViewById(R.id.progress_3);
        progress3.setProgress(40);

        progressBtn = findViewById(R.id.progress_btn);
        progressBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hander.sendEmptyMessage(0);
            }
        });

        progressDialogBtn1 = findViewById(R.id.progress_dialog_btn1);
        progressDialogBtn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog dialog = new ProgressDialog(ProgressActivity.this);
                dialog.setTitle("进度加载");
                dialog.setMessage("请稍等");
                dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        Toast.makeText(ProgressActivity.this,"Cancle",Toast.LENGTH_LONG);
                    }
                });
                dialog.setCancelable(false); // 取消遮罩点击事件
                dialog.show();

            }
        });

        progressDialogBtn2 = findViewById(R.id.progress_dialog_btn2);
        progressDialogBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ProgressDialog dialog = new ProgressDialog(ProgressActivity.this);
                dialog.setTitle("进度提示");
                dialog.setMessage("正在下载");
                dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
                dialog.show();
            }
        });


    }

        // 通过创建匿名类来 来快速实现 重载方法 实现代理等。
    Handler hander = new Handler(){

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (progress3.getProgress() < 100){
                hander.postDelayed(runnable,500);
            }
        }
    };

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            progress3.setProgress(progress3.getProgress() + 5);
            hander.sendEmptyMessage(0);
        }
    };
}

activity_progress.xml

    <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">
    <ProgressBar
        android:id="@+id/progress_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="visible" /> <!--visibility 控制控件可见,不可见,移除-->
    <!--默认 style="@android:style/Widget.Material.ProgressBar"-->

    <ProgressBar
        android:id="@+id/progress_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        style="@android:style/Widget.ProgressBar"/>

    <ProgressBar
        android:id="@+id/progress_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:max="100"
        android:progress="10"
        android:secondaryProgress="30"

        />
    <ProgressBar
        android:id="@+id/progress_4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        style="@android:style/Widget.Material.ProgressBar.Horizontal"
        android:max="100"
        android:progress="10"
        android:secondaryProgress="30"

        />
    <!--max 进度条对应的值。 progress当前进度 secondaryProgress二级进度 progressDrawable 自定义进度图 -->


    <Button
        android:id="@+id/progress_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="模拟进度"/>

    <ProgressBar
        android:id="@+id/progress_5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:indeterminateDrawable="@drawable/bg_progress"
        style="@android:style/Widget.ProgressBar"/>

    <ProgressBar
        android:id="@+id/progress_6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        style="@style/MyProgressBar"/>

    <Button
        android:id="@+id/progress_dialog_btn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="进度提示框"
        android:layout_marginTop="20dp"/>
    <Button
        android:id="@+id/progress_dialog_btn2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="进度提示框"
        android:layout_marginTop="20dp"/>

</LinearLayout>

bg_progress.xml

    <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/nochecked" android:pivotX="50%" android:pivotY="50%">

</animated-rotate>

styles.xml

     <style name="MyProgressBar">
        <item name="android:indeterminateDrawable">@drawable/bg_progress</item>
    </style>

自定义Dialog

activity

      public class CustomDialog extends Dialog {

    private TextView titleView, messageView,cancleView,sureView;

    private String title;
    private String message;
    private String cancleText;
    private String suerText;
    private CancleLister cancleLister;
    private ConfirmLister confirmLister;

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

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



    public CustomDialog setCancleLister(String cancleText, CancleLister cancleLister) {
        this.cancleText = cancleText;
        this.cancleLister = cancleLister;
        return this;
    }

    public CustomDialog setConfirmLister(String suerText, ConfirmLister confirmLister) {
        this.suerText = suerText;
        this.confirmLister = confirmLister;
        return  this;
    }

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

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.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);

        titleView = findViewById(R.id.alert_title);
        messageView = findViewById(R.id.alert_message);
        cancleView = findViewById(R.id.tv_cancle);
        sureView = findViewById(R.id.tv_sure);

        if (!title.isEmpty()){
            titleView.setText(title);
        }
        if (!message.isEmpty()){
            titleView.setText(message);
        }
        if (!cancleText.isEmpty()){
            cancleView.setText(cancleText);
        }
        if (!suerText.isEmpty()){
            sureView.setText(suerText);
        }

        cancleView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cancleLister != null){
                    cancleLister.onClickCancle(CustomDialog.this);
                }
            }
        });
        sureView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (confirmLister != null){
                    confirmLister.onClickConfirm(CustomDialog.this);
                }
            }
        });

    }

    public interface  CancleLister{
        public  void onClickCancle(CustomDialog dialog);

    }

    public interface  ConfirmLister{
        public  void onClickConfirm(CustomDialog dialog);
    }
    
}

custom_dialog.xml

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

    <TextView
        android:id="@+id/alert_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提示"
        android:textSize="20sp"
        android:layout_marginTop="20dp"
        android:textStyle="bold"
        android:textColor="@color/cardview_dark_background"/>

    <TextView
        android:id="@+id/alert_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="删除?"
        android:textSize="20sp"
        android:layout_marginTop="20dp"
        android:textColor="@color/cardview_dark_background"/>


    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:background="@color/colorBlack"
        android:layout_marginTop="20dp"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:orientation="horizontal">
        <TextView
        android:id="@+id/tv_cancle"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="取消"
        android:textSize="20sp"
            android:gravity="center"/>

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

        <TextView
            android:id="@+id/tv_sure"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="确定"
            android:textSize="20sp"
            android:gravity="center"/>
    </LinearLayout>


</LinearLayout>

bg_custom_dialog

  <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <solid android:color="@color/colorWhite"/>
  <corners android:radius="5dp"/>
</shape>

PopupWindow

activity

    public class PopupWindowActivity extends AppCompatActivity {
    private Button popBtn;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popupwindow);
        popBtn = findViewById(R.id.pop_btn);
        popBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                View view = LayoutInflater.from(PopupWindowActivity.this).inflate(R.layout.pop_window,null);
                TextView textView1 = view.findViewById(R.id.popBtn1);
                textView1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(PopupWindowActivity.this,((TextView)v).getText(),Toast.LENGTH_LONG).show();
                    }
                });

                PopupWindow pop = new PopupWindow(view,popBtn.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
                pop.setOutsideTouchable(false); // 取消遮罩点击效果
                pop.setFocusable(true); // 再次点击聚焦 便取消

                pop.showAsDropDown(popBtn);
            }
        });


    }
}

pop_window.xml

      <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/popBtn1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Android"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"/>

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

    <TextView
        android:id="@+id/popBtn2"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="IOS"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"/>

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

    <TextView
        android:id="@+id/popBtn3"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Flutter"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"/>


</LinearLayout>

Activity

Activity创建3部曲

  1. 新建一个类继承Activity或继承其子类
  2. 在AndroidManifest中声明
  3. 创建Layout 并在 Activity的OnCreate中设置

xml 中设置 activity

 <!--  activity   android:theme="@style/AppTheme.NoActionBar"/>  设置 无bar的activity  如何要所有的activity都生效,则在application 中设置-->
android:screenOrientation="landscape  设置横屏竖屏显示,默认portrait 竖屏显示

// 默认启动的Activity
<intent-filter>
              <action android:name="android.intent.action.MAIN" />

              <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>

Activity 的生命周期

image.png

通过在Activity中重新生命周期的方法 来看应用处于什么状态

        protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("Life","....onCreate....");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Life","....onStart....");

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Life","....onResume....");

    }

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

    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Life","....onStop....");

    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Life","....onRestart....");

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Life","....onDestroy....");

    }

Activity的跳转和数据传递

AAJumpActivity

    public class AAJumpActivity extends AppCompatActivity {
    private Button jumpBtn;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activtiy_a);
        jumpBtn = findViewById(R.id.jump_a1);
        jumpBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 显示跳转1  --- 常用
                Intent intent1 = new Intent(AAJumpActivity.this,ABJumpActivity.class);
                //通过Bundle 传递数据
                Bundle  bundle = new Bundle();
                bundle.putString("name","haha");
                bundle.putInt("age",30);
                intent1.putExtras(bundle);
//                startActivity(intent1);
                startActivityForResult(intent1,0);

//                // 显示跳转2
//                Intent intent2 = new Intent();
//                intent2.setClass(AAJumpActivity.this,ABJumpActivity.class);
//                startActivity(intent2);

//                              // 显示跳转3
//                Intent intent3 = new Intent();
//                intent3.setClassName(AAJumpActivity.this,"com.example.hellodemo.jump.ABJumpActivity");
//                startActivity(intent3);

//                // 显示跳转
//                Intent intent4 = new Intent();
//                intent4.setComponent(new ComponentName(AAJumpActivity.this,"\"com.example.hellodemo.jump.ABJumpActivity\""));
//                startActivity(intent4);
//
//                //隐式跳转
//                Intent intent5 = new Intent();
//                intent5.setAction("com.test.ABJumpActivity");
//                startActivity(intent5);
            }
        });


    }
   // 用于下一级Activity数据回调
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d("返回的数据:",data.getExtras().getString("title"));

    }
}

ABJumpActivity

    public class ABJumpActivity extends AppCompatActivity {
    private TextView textView;
    private Button jumpBtn;
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_b);
        textView = findViewById(R.id.jump_b1);

        final Bundle bundle = getIntent().getExtras();
        textView.setText(bundle.getString("name") + ":" + bundle.getInt("age"));

        jumpBtn = findViewById(R.id.jump_b2);
        jumpBtn.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(Activity.RESULT_OK,intent); // 返回数据到上一级
                finish(); //关闭当前Activity
            }
        });

    }
}

Activity的四种启动模式

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

Activity的 android:launchMode属性

  1. standard: 标准模式。 默认的模式。
    (不管栈中有没有,都创建一个新的Activitt)
  2. singleTop: Task栈顶复用模式。
    (当要启动的目标Activity已经位于当前栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onNewIntent()方法会被调用;如果目标不在当前栈顶,则跟standard一样创建新的实例)
  3. singleTask: Task栈内复用模式
    (在同一个任务栈中,如果要启动的目标Activity已经在栈中,则会复用该Activity,并调用onNewIntent()方法,并且该activity上面的activity会被清除;如果栈中没有,则创建新的实例)
    4.singleInstance: 全局单例模式
    (全局复用,不管哪个Task栈,只要存在目标Activity,就复用。每个Activity占有一个新的Task栈)
      public class AAJumpActivity extends AppCompatActivity {
    private Button jumpBtn;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activtiy_a);

        Log.d("AAJumpActivity","---onCreate---");
        Log.d("AAJumpActivity", "taskId" + getTaskId() + ",  hash:" + hashCode());
        logtaskName();
        

    }
   // 用于下一级Activity数据回调
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d("返回的数据:",data.getExtras().getString("title"));

    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d("AAJumpActivity","---onNewIntent---");
        Log.d("AAJumpActivity", "taskId" + getTaskId() + ",  hash:" + hashCode());
        logtaskName();
    }

    private  void logtaskName(){
        try {
            ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
            Log.d("Activity",info.taskAffinity);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }
}

Fragement

  1. Fragement有自己的生命周期
  2. Fragement 依赖于Activity
  3. Fragement 通过getActivity()可以获取所在的Activity, Activity可以通过FragementManager的 findFragementById()或者 findFragementByTag() 获取 Fragement
  4. Fragement 和 Activity是多对多的关系

fragement 可以认为是 碎片化的Activity

实例:
创建子视图 Fragement
AFragement

  public class AFragement extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragement_a,container,false);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView textView = view.findViewById(R.id.fragement_a);
        textView.setText("我是AFragement");

    }
}

**fragement_a.xml**

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <TextView
        android:id="@+id/fragement_a"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:gravity="center"
        />

</LinearLayout>

BFragement

  public class BFragement extends Fragment {

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        TextView textView = view.findViewById(R.id.fragement_b);
        textView.setText("我是BFragement");

    }
}
**fragement_b.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <TextView
        android:id="@+id/fragement_b"

        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:gravity="center"

        />

</LinearLayout>

ContainsActivity

    public class ContainsActivity extends AppCompatActivity {
    private Button containsBtn;
    private AFragement aFragement;
    private BFragement bFragement;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contains);

        containsBtn = findViewById(R.id.container_b);
        containsBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bFragement == null){
                    bFragement = new BFragement();
                }
                getSupportFragmentManager().beginTransaction().replace(R.id.container_f,bFragement).commitAllowingStateLoss();
            }
        });

        // 实例化AFragement
        aFragement = new AFragement();
        //Fragement添加到Activity中 记得commit
        getSupportFragmentManager().beginTransaction().add(R.id.container_f,aFragement).commitAllowingStateLoss();
    }

**activity_contains.xml**
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CheckBoxActivity">

    <Button
        android:id="@+id/container_b"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="切换BFrament"/>
    <FrameLayout
        android:id="@+id/container_f"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/container_b">

    </FrameLayout>

</RelativeLayout>

Fragement中调用 getActivity() 为null 的问题

      @Override
    public void onAttach(@NonNull Context context) {  // Activity 与 Fragement 绑定关系时调用
        super.onAttach(context);
    }

    @Override
    public void onDetach() {   // Activity 与 Fragement 解除关系时调用     注意 一旦解除了关系 getActivity()就是null 要注意安全判断
        super.onDetach();
    }

    @Override
    public void onDestroy() {   // Fragement销毁时调用
        super.onDestroy();
    }

向Fragement 传递参数

      // 实例化AFragement
        aFragement = new AFragement();
        Bundle bundle = new Bundle();
        bundle.putString("title","船只");
        aFragement.setArguments(bundle);
        //Fragement添加到Activity中 记得commit
        getSupportFragmentManager().beginTransaction().add(R.id.container_f,aFragement).commitAllowingStateLoss();

// 获取值
 if (getArguments() != null){
            textView.setText(getArguments().getString("title"));
        }

Fragement回退栈

 通过   addToBackStack()方法实现。 他会把原来的状态保存到栈中。
                /*  addToBackStack  当我添加新的Fragement 时 如何 我们想点返回键回到之前的状态 而不是退出Activity 可以用这个方法
                    在Fragement视图切换时,如果用 hide A, add B 则 AFragement渲染的视图对象还是在的, 返回时还是原状态 不会调用onCreateView 方法
                    如果 用 replace 将 B替换成A 则AFragement绑定的View对象则释放。 返回时,重新创建,调用不会调用onCreateView。

                * */
                getSupportFragmentManager().beginTransaction().replace(R.id.container_f,bFragement).addToBackStack(null).commitAllowingStateLoss();
                getSupportFragmentManager().beginTransaction().hide(aFragement).add(R.id.container_f,bFragement).addToBackStack(null).commitAllowingStateLoss();

Fragement与Activity通信

可以通过 在Fragement中 通过 getAtivity() 获取Activity对象 然后通过他自己的方法传值
通过接口实现代理委托模式。 来进行事件回调。

Android的事件处理

当用户在应用界面上执行各种操作时,应用程序需为用户的动作提供响应,这种响应的过程就是事件处理

从开发角度或者调用方式可分为:

》基于监听的事件处理机制

监听三要素

Event Source(时间源)
Event(事件)
Event Listener(事件监听器)

实例1:

    // btn是事件源     OnClickListener是监听器。 点击事件比较简单单一 没有传出Event事件对象,对于触摸事件,键盘事件 还是要传事件本身的
       btn.setOnClickListener(new View.OnClickListener() { 
          @Override
          public void onClick(View v) {
              Toast.makeText(ButtonActivity.this,"btn被点击了",Toast.LENGTH_SHORT).show();
          }
      });

实例2:

    // btn 事件源   OnTouchListener事件监听器  event
     btn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        Log.d("setOnTouchListener","...onTouch...ACTION_DOWN");

                        break;
                    case MotionEvent.ACTION_UP:
                        Log.d("setOnTouchListener","...onTouch...ACTION_UP");
                        break;
                }

                return false;
            }
        });

给同一事件源添加多个同种类型监听器,后台添加的后覆盖前面的。
监听器的实现方式: 通过接口的委托代理模式实现。

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

》基于回调的事件处理机制

》回调机制和监听机制的区别:
监听机制 事件源和监听器是分开的。 回调机制:事件源和监听器是绑在一起的。对于按钮,如果要通过回调机制来处理事件 就要继承按钮,重写事件处理方法,因为按钮本身实现了监听器。

事件的传播与处理

事件通过响应者链进行传播。 当用户点击屏幕时,应用会从根据可响应组件的层级生成一个响应者链。从最上层组件 进行处理。通过 该组件是否接受该事件的处理 来判断事件是否向下一层传递。 如果接受则事件不再传递,也就是组件事件的回调为true, 如果返回为false,则不接受事件,事件可继续传递。 Button等特殊组件默认接受事件 isClickable。

优先级:
组件的监听机制处理 > 回调机制处理 > 其他组件。

如果组件没有实现事件处理,Button等默认接受,不再向下处理。其他组件默认不接受,向下传递。
事件先回判断是否有 监听机制处理,有则按照监听机制的处理。如果监听机制返回true ,则不再传递, 如果没有或者返回false ;则 判断是否有 回调机制处理,如果有且返回true则不传递,如果没有或者返回false 则 传递给下一级组件处理。
实现onclick的监听器 会使组件isClickable可点击 返回true;

  public class ButtonActivity extends AppCompatActivity {
    private Button btn;
    private Button myButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button);
        btn = findViewById(R.id.btn_three);
        myButton = findViewById(R.id.myButton);


 1.       myButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                }
                // false 不接受事件,则判断是否有回调处理,如果有则传给回调处理,如果没有 传递给下一级组件处理。 true 接受事件。事件不再向下传递

                Log.d("监听机制处理","...onTouch...ACTION_UP");

                return false;
            }
        });

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("activity","onTouchEvent");
        return super.onTouchEvent(event);
    }

3.    public  void showToast(View view){
        Toast.makeText(this,"btn被点击了",Toast.LENGTH_SHORT).show();
    }
}


import androidx.appcompat.widget.AppCompatButton;

public class MyButton extends AppCompatButton {
    public MyButton(Context context) {
        super(context);
    }

    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /*
    回调机制处理:
    监听器和事件源绑定
    实现监听方法处理事件。
    * */
    @Override
2    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        Log.d("回调机制处理:","onTouchEvent");

        // false 不接受事件 传递给下一级组件处理。 true 接受事件。事件不再向下传递

        return false;
    }
}

View的事件分发

  • dispatchTouchEvent -->setOnTouchListener->onTouchEvent
  • onClick/onLongClick来自onTouchEvent的处理

Handler消息处理

主要用途
》未来某时做某事
》线程间通信
实例

      public class HanderActivity extends AppCompatActivity {
    private Handler handler;
    private Button handerBtn1,handerBtn2;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hander);
        handler = new Handler(){
            @NonNull
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                    case 1:
                        Log.d("hander","线程通信");

                        finish(); // 返回上一个界面
                        break;
                }
            }
        };

        handerBtn1 = findViewById(R.id.hander_btn1);
        handerBtn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("hander","延迟调用");
                // 延迟条用
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(HanderActivity.this,"发送消息",Toast.LENGTH_LONG).show();
                    }
                },3000);

            }
        });

        handerBtn2 = findViewById(R.id.hander_btn2);
        handerBtn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    new Thread(){
                        @Override
                        public void run() {
                            super.run();
                            Message message = new Message();
                            message.what = 1;
                            handler.sendMessage(message);
                        }
                    }.start();
            }
        });

    }
}

数据存储

》SharedPreferenes 轻量数据存储

Xml文件,K-V形式
SharedPreferences 读
SharedPreferences.Editor 写
文件目录: /data/data/<applicationId>/shared_prefs (需要root才能看到)

    public class SharedPreferencesActivity extends AppCompatActivity {
    private Button getBtn,saveBtn;
    private EditText editText;
    private TextView textView;
    private SharedPreferences sharedPreferences;
    private SharedPreferences.Editor editor;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shared_preferences);

        sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
        editor = sharedPreferences.edit();
        /*
        *    查看 data 存放
        * CodeYYdeMacBook-Pro:~ codeyy$ adb shell
generic_x86:/ $ run-as com.example.hellodemo
generic_x86:/data/data/com.example.hellodemo $ ls
cache code_cache shared_prefs
generic_x86:/data/data/com.example.hellodemo $ cd shared_prefs
generic_x86:/data/data/com.example.hellodemo/shared_prefs $ ls
data.xml
        *
        * */
        getBtn = findViewById(R.id.sharedpreference_get);
        saveBtn = findViewById(R.id.sharedpreference_save);
        editText = findViewById(R.id.sharedpreference_et);
        textView = findViewById(R.id.sharedpreference_tv);

        saveBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                editor.putString("name",editText.getText().toString());
                editor.apply(); // 写入内存和磁盘
            }
        });

        getBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(sharedPreferences.getString("name",""));
            }
        });

    }
}

》Android的存储概念

image.png image.png image.png

》File

利用Java的I/O流
FileOutputStream FileInputStream

File 内部存储

      // 存储数据
    public void save(String content){
        FileOutputStream outputStream = null;
        try {
            outputStream = openFileOutput(fileName,MODE_PRIVATE);
            outputStream.write(content.getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (outputStream != null){
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    // 读取数据
    private String read(){
        FileInputStream inputStream = null;

        try {
            inputStream = openFileInput(fileName);
            byte[] buff = new byte[1024];
            StringBuffer sb = new StringBuffer("");
            int len = 0;
            while ((len = inputStream.read(buff)) > 0){
                sb.append(new String(buff,0,len));
            }
            return sb.toString();

        }catch (IOException e){

        }finally {
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        return null;
    }

File 外部存储

广播

LocalBroadcastManager 应用内广播

发送广播

    public class Broad2Activity extends AppCompatActivity {
    private Button sendBtn;
    private EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broad2);
        sendBtn = findViewById(R.id.broad3);
        sendBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (editText.getText().toString().length() != 0){
                    // 发送消息
                    Intent intent = new Intent("updateText");
                    intent.putExtra("title",editText.getText().toString());
                    LocalBroadcastManager.getInstance(Broad2Activity.this).sendBroadcast(intent);
                }
            }
        });

        editText = findViewById(R.id.broad4);

    }
}

接受广播

      public class BroadActivity extends AppCompatActivity {
    private Button nextBtn;
    private TextView textView;
    private BroadcastReceiver receiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_broad);

        nextBtn = findViewById(R.id.broad1);
        nextBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(BroadActivity.this,Broad2Activity.class);
                startActivity(intent);

            }
        });

        textView = findViewById(R.id.broad2);

        // 广播监听器
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
               switch (intent.getAction()){
                   case "updateText":
                       textView.setText(intent.getStringExtra("title"));
                       break;
               }
            }
        };
        // 过滤
        IntentFilter filter = new IntentFilter();
        filter.addAction("updateText");
        // 注册广播
        LocalBroadcastManager.getInstance(BroadActivity.this).registerReceiver(receiver,filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除广播监听器
        LocalBroadcastManager.getInstance(BroadActivity.this).unregisterReceiver(receiver);
    }
}

补间动画和属性动画

补间动画(平移,旋转,透明度的变化等) 是视觉上的一个效果,属性实际并没有发生改变。如果你打印坐标,或是加点击事件会发现在原来的地方才会生效。
属性动画: 属性真正的发生了改变。

属性动画
》ValueAnimator
》 ObjectAnimator.ofFloat()
translationX translationY alpha rotation rotationX...

    public class ObjectAnimationActivity extends AppCompatActivity {
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_object_animation);
        textView = findViewById(R.id.animation_tx);

       //  translationX() 动画到哪 , translationXBy() 动画执行多少
        textView.animate().translationXBy(100).setDuration(3000).start();
        textView.animate().alpha(0).setDuration(3000).start();


        ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
        valueAnimator.setDuration(2000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // valueAnimator实际值
                Log.d("valueAnimator",animation.getAnimatedValue() + "");
                // 动画的进度 0-1
                Log.d("valueAnimator",animation.getAnimatedFraction() + "");

                textView.setX(new Float(animation.getAnimatedValue().toString()));
            }
        });
        valueAnimator.start();

      
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView,"translationY",0,500,200,800);
        objectAnimator.setDuration(2000);
        objectAnimator.start();

    }
}

相关文章

网友评论

      本文标题:Android开发第一天

      本文链接:https://www.haomeiwen.com/subject/jticzctx.html