控件
WebView
用于加载网页元素:
继承关系:WebView -> MockView
- 加载URL(网络或本地assets文件夹下的html文件)
Webview.loadUrl("https://...") //可以加载assets文件夹下的html文件
Webview.loadUrl("file:///android_asset/….")
- 加载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内页面后退,需要复写onKeyDown方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) { //复写onKeyDown方法
if(keyCode == KeyEvent.KEYCODE_BACK && mWV.canGoBack()) {
mWV.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
- 在使用WebView控件时常用的一些方法和类:
当下属方法或者类使用达不到效果,很可能是app没有网络访问权限,需要在Manifest文件中加入: <uses-permission android:name="android.permission.INTERNET" />
private WebView mWV;
mWV = findViewById(R.id.);
mWV.getSettings().setJavaScriptEnabled(true);
//当加载需要JavaScript支持的网页时,需要加上这一句
//---------------------------------------------------------------------//
mWV.setWebViewClient(new MyWebViewClient());
//防止WebView跳转到手机浏览器打开网页,而使用webview打开
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"); //用于在logcat中输出tag和一段字符串,可以不写,下同
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d("WebView","onPageFinished");
}
}
//---------------------------------------------------------------------//
mWV.setWebChromeClient(new MyWebChromeClient());
//监听网页信息并利用这些信息对app进行操作
class MyWebChromeClient extends WebChromeClient{
public MyWebChromeClient() {
super();
}
@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);
}
}
Toast
消息提示组件
- 常用样式:
Toast.makeText(getApplicationContext(),"defaulttoast",Toast.LENGTH_LONG).show();
- 自定义显示位置:
Toast toast=Toast.makeText(getApplicationContext(),"",Toast.LENGTH_LONG);
//Toast的makeText方法会返回一个toast类的对象
toast.setText("hello");
toast.setGravity(Gravity.CENTER,0,0);
//设置Toast居中显示
toast.show();
- 自定义显示内容(图片、文本)
Toast customToast = new Toast(getApplicationContext());
LayoutInflater inflatr = LayoutInflater.from(ToastActivity.this);
Viewview = inflater.inflate(R.layout.layout_toast,null);
//自定义一个layout布局文件,此布局文件就是自定义内容模版
TextViewtextView = view.findViewById(R.id.tv);
ImageViewimageView = view.findViewById(R.id.iv);
textView.setText("test");
//为自定义模版中的Text组件设置内容
imageView.setImageResource(R.drawable.ic_launcher_foreground);
//设置图像
customToast.setView(view);
//将模版应用到Toast对象上
customToast.setDuration(Toast.LENGTH_LONG);
//设置显示时间
customToast.show();
- 简单封装(这样可以防止多次toast排队显示,也可以被其他Activity直接引用)
public class ToastUtil{
public static ToastmToast;
public static void showMsg(Contextcontext,StringMsg){
if(mToast == null){
mToast = Toast.makeText(context,Msg,Toast.LENGTH_LONG);
}else{
mToast.setText(Msg);
}
mToast.show();
}
}
封装后的调用格式:
ToastUtil.showMsg(getApplicationContext(),"封装的Toast");
ProgressBar
-
没有监听器
-
支持自定义样式
例如可以如下定义一个style
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/icon_status_progress" //进度条图片
android:pivotX="50%" //旋转中心的x坐标在图片宽度的50%处
android:pivotY="50%"> ////旋转中心的y坐标在图片高度的50%处
</animated-rotate>
然后在xml文件的一个progress控件中使用下述语句调用该style
android:indeterminateDrawable="@drawable/background_progress"
- 常用属性
Style:Horizontal (Small. Large. Inverse. Small.Inverse. Large.Inverse)
Max: //设置进度条最大值
Progress: //设置进度条当前进度
secondaryProgress: //设置进度条第二进度,一般用作播放器的缓冲进度
- 常用方法:
Boolean isIndeterminate () //设置进度条的模式,indeterminate模式“圆形旋转”:true,条形模式:false
incrementProgressBy (int)
incrementsecondaryProgressBy (int)
SeekBar
用户可调节的进度条
- 监听器:
msb1.setOnSeekBarChangeListener(newSeekBar.OnSeekBarChangeListener(){
@Override
publicvoidonProgressChanged(SeekBarseekBar,intprogress,booleanfromUser){
//fromUser用于区分本次进度改变是否来自于用户
}
@Override
publicvoidonStartTrackingTouch(SeekBarseekBar){
}
@Override
publicvoidonStopTrackingTouch(SeekBarseekBar){
}
});
RatingBar
- 监听器:
mRb1.setOnRatingBarChangeListener(newRatingBar.OnRatingBarChangeListener(){
@Override
publicvoidonRatingChanged(RatingBarratingBar,floatrating,booleanfromUser){
if(fromUser){
Toast.makeText(TimePickerActivity.this,rating+"评价",Toast.LENGTH_SHORT).show();
}
}
});
- 属性:
StepSize //每次移动的最小距离(多少星)
Numstart //整个进度条星星的个数
AlertDialog
- 设计一般型AlertDialog,可以设置positivebutton,neutralbutton和negativebutton三种按钮,并可以为每个按钮设置监听器(注意监听器类型为
DialogInterface.OnClickListener()
),监听器的参数分别代表被点击的dialog对象和该对象中被点击的按钮标号。
AlertDialog.Builder builder = new AlertDialog.Builder(AlertDialogActivity.this);
builder.setTitle("Please answer").setMessage("how are you?").setIcon(R.drawable.ic_launcher_foreground)
.setPositiveButton("I'm fine!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ToastUtil.showMsg(AlertDialogActivity.this,"thank you, and you?");
}
}).setNeutralButton("not too bad.", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ToastUtil.showMsg(AlertDialogActivity.this,"tomorrow will be better!");
}
}).setNegativeButton("not very well.", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ToastUtil.showMsg(AlertDialogActivity.this,"hope you have a nice day");
}
}).show();
注意最后要调用.show()方法,不然最后不会显示dialog对话框。
- 设置单选型dialog
final String[] nation = new String[]{"Han","minority"};
AlertDialog.Builder builder3 = new AlertDialog.Builder(AlertDialogActivity.this);
builder3.setTitle("choose your nation: ").setSingleChoiceItems(nation, 1, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ToastUtil.showMsg(AlertDialogActivity.this,nation[which]);
dialog.dismiss(); //点击以后关闭dialog
}
}).setCancelable(false).show(); //点击空白处不可关闭dialog
注意需要将string数组设置为final类型,否则无法在内部类中调用
- 设置多选型dialog,在多选型dialog中需要使用一个boolean型数组来设置多选按钮的初始状态。
final String[] action = new String[]{"sing","dance","rap"};
boolean[] seclected = new boolean[]{false,false,false};
AlertDialog.Builder builder4 = new AlertDialog.Builder(AlertDialogActivity.this);
builder4.setMultiChoiceItems(action, seclected, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
ToastUtil.showMsg(AlertDialogActivity.this,action[which] + ":" + isChecked);
}
}).setPositiveButton("confirm", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
- 自定义dialog
使用
LayoutInflater.from(AlertDialogActivity.this).inflate(R.layout.layout_dialog,null);
语句通过inflater对象使用layout布局生成一个view对象,该view对象作为模版设置给一个AlertDialog的builder对象。同时可以对模版中的各个控件动态修改。
inal AlertDialog.Builder builder5 = new AlertDialog.Builder(AlertDialogActivity.this);
View view = LayoutInflater.from(AlertDialogActivity.this).inflate(R.layout.layout_dialog,null);
Button button = view.findViewById(R.id.btn_login);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
builder5.setTitle("Please login first.").setView(view).show();
技巧
使用handler和Runnable实现进度条进度的动态增加
mProgressBar2 = findViewById(R.id.pb_2);
mbtnStart = findViewById(R.id.btn_start);
mbtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.sendEmptyMessage(0);
Toast.makeText(ProgressBarActivity.this,"click",Toast.LENGTH_SHORT).show();
}
});
}
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if(mProgressBar2.getProgress() < 100){
mProgressBar2.postDelayed(runnable,500);
}else{
ToastUtil.showMsg(ProgressBarActivity.this,"progress complete");
}
}
};
Runnable runnable = new Runnable() {
@Override
public void run() {
mProgressBar2.setProgress(mProgressBar2.getProgress() + 5);
handler.sendEmptyMessage(0);
}
};
定义函数时可以将巧妙的设置返回值类型,实现连续调用:
例如:
public CustomDialog setTitle(String title) {
Title = title;
return this;
}
这样定义CustomDialog的set类函数,就可以对一个对象连续调用其set方法,快速赋值。
使用switch语句和自定义clickListener管理众多button:
例如:
mBtnToast = findViewById(R.id.btn_toast);
mAlertDialog = findViewById(R.id.btn_alertdialog);
mProgressBar = findViewById(R.id.btn_progressbar);
mCustomDialog = findViewById(R.id.btn_custondialog);
private void setListeners(){
OnClick onClick = new OnClick(); mBtnToast.setOnClickListener(onClick);
mAlertDialog.setOnClickListener(onClick);
mProgressBar.setOnClickListener(onClick);
mCustomDialog.setOnClickListener(onClick);
}
private class OnClick implements View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent = null;
switch (v.getId()){
case R.id.btn_toast:
//转到Toast
intent = new Intent(UIActivity.this,ToastActivity.class);
break;
case R.id.btn_alertdialog:
//转到AlertDialog
intent = new Intent(UIActivity.this,AlertDialogActivity.class);
break;
case R.id.btn_progressbar:
//
intent = new Intent(UIActivity.this, ProgressBarActivity.class);
break;
case R.id.btn_custondialog:
//
intent = new Intent(UIActivity.this,CustomDialogActivity.class);
break;
}
startActivity(intent);
使用View控件设置分割线:
例如:
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/colorBlack"/>
自定义Dialog(CustomDialog)
- 第一步设计CustommDialog的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
android:padding="10dp"
android:background="@drawable/layout_custom_dialog">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="confirm to delete?"
android:textSize="20sp"
android:layout_marginTop="10dp"/>
<View
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/colorBlack"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_confirm"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:text="confirm"
android:layout_weight="1"/>
<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="@color/colorBlack"/>
<Button
android:id="@+id/btn_cancel"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:text="cancel"
android:layout_weight="1"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/colorBlack"/>
</LinearLayout>
- 第二步定义一个CustomDialog类,并在该类的onCreat方法中调用上述布局文件实现CustomDailog。
package com.example.myfirstapplication.widget;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.example.myfirstapplication.R;
import com.example.myfirstapplication.Util.ToastUtil;
public class CustomDialog extends Dialog implements View.OnClickListener{
//继承Dialog类,同时实现onclicklistener方法,
让自定义dailog既可以有dialog的属性和方法,还可以快速实现点击。
private TextView mTvTitle,mTvMessage;
private Button mBtnConfirm,mBtnCancel;
private IOnCancelListener cancelListener;
private IOnConfirmListener confirmListener;
private String Title,Message,Cancel,Confirm;
//复写Dialog构造函数
public CustomDialog(@NonNull Context context) {
super(context);
}
public CustomDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
}
protected CustomDialog(@NonNull Context context, boolean cancelable, @Nullable OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
}
//定义CustomDialog的属性设置函数,和AlertDialog类中的对应函数功能相同
public CustomDialog setTitle(String title) {
Title = title;
return this;
}
public CustomDialog setMessage(String message) {
Message = message;
return this;
}
public CustomDialog setCancel(String cancel,IOnCancelListener listener) {
Cancel = cancel;
this.cancelListener = listener;
return this;
}
public CustomDialog setConfirm(String confirm,IOnConfirmListener listener) {
Confirm = confirm;
this.confirmListener = listener;
return this;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_custom_dialog);
//获取当前屏幕宽度
WindowManager manager = getWindow().getWindowManager();
Display display = manager.getDefaultDisplay();
WindowManager.LayoutParams params = getWindow().getAttributes();
//设置控件宽度为屏幕宽度的80%
Point size = new Point();
display.getSize(size);
params.width = (int)(size.x * 0.8);
getWindow().setAttributes(params);
mTvMessage = findViewById(R.id.tv_message);
mTvTitle = findViewById(R.id.tv_title);
mBtnCancel = findViewById(R.id.btn_cancel);
mBtnConfirm = findViewById(R.id.btn_confirm);
// 初始化CustomDialog的各个属性
if(!TextUtils.isEmpty(Title)){
mTvTitle.setText(Title);
}
if(!TextUtils.isEmpty(Message)){
mTvMessage.setText(Message);
}
if(!TextUtils.isEmpty(Cancel)){
mBtnCancel.setText(Cancel);
}
if(!TextUtils.isEmpty(Confirm)){
mBtnConfirm.setText(Confirm);
}
mBtnCancel.setOnClickListener(this);
mBtnConfirm.setOnClickListener(this);
}
// 复写onClickListner借口的onClikc方法
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_cancel:
if(cancelListener != null){
cancelListener.OnCancel(this);
dismiss();
}
break;
case R.id.btn_confirm:
if(confirmListener != null){
confirmListener.OnConfirm(this);
dismiss();
}
break;
}
}
//自定义接口
public interface IOnCancelListener{
void OnCancel(Dialog dialog);
}
public interface IOnConfirmListener{
void OnConfirm(Dialog dialog);
}
}
- 第三步,定义一个Activity,在该activity实例化CustomDialog类,复写CustomDialog类中的接口,自定义两个按钮的功能,调用set方法自定义Dialog的各种信息
package com.example.myfirstapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import com.example.myfirstapplication.Util.ToastUtil;
import com.example.myfirstapplication.widget.CustomDialog;
public class CustomDialogActivity extends AppCompatActivity {
private Button mBtnCustomDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_dialog);
mBtnCustomDialog = findViewById(R.id.btn_CustomDialog);
mBtnCustomDialog.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CustomDialog customDialog = new CustomDialog(CustomDialogActivity.this);
customDialog.setTitle("提示").setMessage("确认删除此项?").setCancel("取消", new CustomDialog.IOnCancelListener() {
@Override
public void OnCancel(Dialog dialog) {
ToastUtil.showMsg(CustomDialogActivity.this,"cancel...");
}
}).setConfirm("确认", new CustomDialog.IOnConfirmListener() {
@Override
public void OnConfirm(Dialog dialog) {
ToastUtil.showMsg(CustomDialogActivity.this,"confirm...");
}
}).show();
}
});
}
}
实现效果: