图标平台
Android学习论坛
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
<?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部曲
- 新建一个类继承Activity或继承其子类
- 在AndroidManifest中声明
- 创建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属性
- standard: 标准模式。 默认的模式。
(不管栈中有没有,都创建一个新的Activitt)- singleTop: Task栈顶复用模式。
(当要启动的目标Activity已经位于当前栈顶时,不会创建新的实例,会复用栈顶的Activity,并且其onNewIntent()方法会被调用;如果目标不在当前栈顶,则跟standard一样创建新的实例)- 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
- Fragement有自己的生命周期
- Fragement 依赖于Activity
- Fragement 通过getActivity()可以获取所在的Activity, Activity可以通过FragementManager的 findFragementById()或者 findFragementByTag() 获取 Fragement
- 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();
}
}
网友评论