简要目录
- 1、复杂组件的使用
- 1、组件通用
- 2、列表ListView的使用(上)
- 2、列表ListView的使用(下)
- 3、优化跳转界面
- 3、横向列表HorizontalListView(自定义View)的使用
- 4、网格列表GridView的使用
- 5、静态进度条xxxBar的使用
- 5、动态进度条xxxBar的使用
- 6、网页显示WebView的使用(类似于iframe)
- 7、碎片界面Fragment的使用(类似于vue layout内部的界面)
- 8、轮播组件ViewPager的使用
- 9、轮播组件ViewPager+Fragment+TabLayout的使用
- 10、侧滑菜单栏 SlidingPaneLayout || DrawerLayout的使用
- 10、下拉刷新SwipeRefreshLayout的使用
1、复杂组件的使用
1、组件通用
1.1 控制组件显示状态
- xml属性控制:
- java属性控制:
// View 为当前正在使用的控件
View.setVisibility(View.GONE) 控件隐藏
View.setVisibility(View.VISIBLE) 控件展示
1.2 设置触摸激活状态(只读)
- java控制(setEnabled)
View.setEnabled(false);
1.3 自定义样式
自定义样式: drawable文件创建xml
在控件中引用即可
2、列表ListView的使用(上)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activitys.ListViewTest">
<ListView
android:id="@+id/listView_lv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
2.1 属性
2.2 事件
2.3 适配器
2.3.1 ArrayAdapter(简单数组适配器)
public class ListViewTest extends AppCompatActivity {
private ListView mListViewLvTest;
private List<String> list;
private ArrayAdapter<String> arrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_test);
initView();
setView();
}
private void setView() {
mListViewLvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(),"点击"+list.get(i), Toast.LENGTH_LONG).show();
}
});
}
private void initView() {
mListViewLvTest = (ListView) findViewById(R.id.listView_lv_test);
list = new ArrayList<>();
list.add("数据1");
list.add("数据2");
list.add("数据3");
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
mListViewLvTest.setAdapter(arrayAdapter);
}
}
2.3.2 BaseAdapter(自定义适配器)
2.3.2.1 准备自定义的View模版
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:padding="10dp"
android:layout_height="match_parent">
<!-- 这里的text不重要,只是一个提示作用-->
<TextView
android:id="@+id/adapter_listview_tv_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
android:text="name"/>
<TextView
android:id="@+id/adapter_listview_tv_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15dp"
android:text="age"/>
</LinearLayout>
2.3.2.2 准备数据的实体类
package com.example.study1.entity;
public class ListViewEntity {
private String name;
private Integer age;
public ListViewEntity() {
}
public ListViewEntity(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "ListViewEntity{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.3.2.3 准备实体的数据
listViewEntities = new ArrayList<>();
listViewEntities.add(new ListViewEntity("张三",14));
listViewEntities.add(new ListViewEntity("李四",14));
listViewEntities.add(new ListViewEntity("王五",14));
2.3.2.4 准备一个自定义的BaseAdapter的类
private class ListViewAdapter extends BaseAdapter{
@Override
public int getCount() {
return listViewEntities.size();
}
@Override
public Object getItem(int i) {
return listViewEntities.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
// 渲染数据的方法
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder vh = null;
if(view == null){
vh = new ViewHolder();
// LayoutInflater.from(从哪个上下文) 获得LayoutInflater界面布局加载类
// java获得一个静态界面的view对象采用的获得LayoutInflater.inflate(加载哪个界面的布局)
view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.adapter_listview_test, null);
vh.tvName = view.findViewById(R.id.adapter_listview_tv_name);
vh.tvAge = view.findViewById(R.id.adapter_listview_tv_age);
// 打包,存放到现在的界面当中
view.setTag(vh);
}else{
vh = (ViewHolder) view.getTag();
}
// 处理数据
vh.tvName.setText("名字:"+ listViewEntities.get(i).getName());
vh.tvAge.setText("年龄:"+ listViewEntities.get(i).getAge());
return view;
}
// 类似于DTO,方便抽出操作
class ViewHolder{
TextView tvName;
TextView tvAge;
}
}
1.3.2.4 为原来的ListView设置自定义适配器
private void initView() {
mListViewLvTest = (ListView) findViewById(R.id.listView_lv_test);
listViewEntities = new ArrayList<>();
listViewEntities.add(new ListViewEntity("张三",14));
listViewEntities.add(new ListViewEntity("李四",14));
listViewEntities.add(new ListViewEntity("王五",14));
listViewAdapter = new ListViewAdapter();
mListViewLvTest.setAdapter(listViewAdapter);
}
2、列表ListView的使用(下)
2.1 插件
==2020.3 AS无法使用该插件 ==
3、优化跳转界面
3.1 普通的跳转方法
只要当前的界面继承了AppCompatActivity类,就会有startActivity()跳转方法
// new Intent(当前上下文的对象, 跳转到那里)
startActivity(new Intent(getApplicationContext(), ImageViewTest.class));
3.2 优化跳转方法
public void onClick(View view) {
// 根据点击元素(布局拦)进行相应的跳转效果
//Intent intent = new Intent(getApplicationContext(), ImageViewTest.class);
//startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
// ListViewTest.this, new Pair[]{Pair.<View, String>create(holder.adapter_listview_layout, "set_Img")}
//).toBundle());
// 根据点击元素(图片)进行相应的跳转效果
Intent intent = new Intent(getApplicationContext(), ImageViewTest.class);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(
ListViewTest.this, new Pair[]{Pair.<View, String>create(holder.adapter_listview_iv_test, "set_Img")}
).toBundle());
}
在跳转到的相应界面对相应元素进行绑定,设置跳转效果
android:transitionName="set_Img"
3、横向列表HorizontalListView(自定义View)的使用
3.1 简单自定义View的理解
- 通过java程序构成xml样式
- 直接可以在xml中使用
- 导出属性
- …
原文地址
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
import java.util.LinkedList;
import java.util.Queue;
public class HorizontalListView extends AdapterView<ListAdapter> {
float startX;
float startY;
public boolean mAlwaysOverrideTouch = true;
protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false;
public HorizontalListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
private synchronized void initView() {
mLeftViewIndex = -1;
mRightViewIndex = 0;
mDisplayOffset = 0;
mCurrentX = 0;
mNextX = 0;
mMaxX = Integer.MAX_VALUE;
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
}
@Override
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
mOnItemSelected = listener;
}
@Override
public void setOnItemClickListener(OnItemClickListener listener) {
mOnItemClicked = listener;
}
@Override
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClicked = listener;
}
private DataSetObserver mDataObserver = new DataSetObserver() {
@Override
public void onChanged() {
synchronized (HorizontalListView.this) {
mDataChanged = true;
}
invalidate();
requestLayout();
}
@Override
public void onInvalidated() {
reset();
invalidate();
requestLayout();
}
};
@Override
public ListAdapter getAdapter() {
return mAdapter;
}
@Override
public View getSelectedView() {
return null;
}
@Override
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mDataObserver);
reset();
}
private synchronized void reset() {
initView();
removeAllViewsInLayout();
requestLayout();
}
@Override
public void setSelection(int position) {
}
private void addAndMeasureChild(final View child, int viewPos) {
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
}
addViewInLayout(child, viewPos, params, true);
child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
}
@Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mAdapter == null) {
return;
}
if (mDataChanged) {
int oldCurrentX = mCurrentX;
initView();
removeAllViewsInLayout();
mNextX = oldCurrentX;
mDataChanged = false;
}
if (mScroller.computeScrollOffset()) {
int scrollx = mScroller.getCurrX();
mNextX = scrollx;
}
if (mNextX <= 0) {
mNextX = 0;
mScroller.forceFinished(true);
}
if (mNextX >= mMaxX) {
mNextX = mMaxX;
mScroller.forceFinished(true);
}
int dx = mCurrentX - mNextX;
removeNonVisibleItems(dx);
fillList(dx);
positionItems(dx);
mCurrentX = mNextX;
if (!mScroller.isFinished()) {
post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
}
}
private void fillList(final int dx) {
int edge = 0;
View child = getChildAt(getChildCount() - 1);
if (child != null) {
edge = child.getRight();
}
fillListRight(edge, dx);
edge = 0;
child = getChildAt(0);
if (child != null) {
edge = child.getLeft();
}
fillListLeft(edge, dx);
}
private void fillListRight(int rightEdge, final int dx) {
while (rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) {
View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, -1);
rightEdge += child.getMeasuredWidth();
if (mRightViewIndex == mAdapter.getCount() - 1) {
mMaxX = mCurrentX + rightEdge - getWidth();
}
if (mMaxX < 0) {
mMaxX = 0;
}
mRightViewIndex++;
}
}
private void fillListLeft(int leftEdge, final int dx) {
while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
}
private void removeNonVisibleItems(final int dx) {
View child = getChildAt(0);
while (child != null && child.getRight() + dx <= 0) {
mDisplayOffset += child.getMeasuredWidth();
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mLeftViewIndex++;
child = getChildAt(0);
}
child = getChildAt(getChildCount() - 1);
while (child != null && child.getLeft() + dx >= getWidth()) {
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mRightViewIndex--;
child = getChildAt(getChildCount() - 1);
}
}
private void positionItems(final int dx) {
if (getChildCount() > 0) {
mDisplayOffset += dx;
int left = mDisplayOffset;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
left += childWidth + child.getPaddingRight();
}
}
}
public synchronized void scrollTo(int x) {
mScroller.startScroll(mNextX, 0, x - mNextX, 0);
requestLayout();
}
/**
* 上下滑动需要拦截,
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean handled = super.dispatchTouchEvent(ev);
handled |= mGesture.onTouchEvent(ev);
getParent().requestDisallowInterceptTouchEvent(true);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) ev.getX();
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
int endX = (int) ev.getX();
int endY = (int) ev.getY();
int dx = (int) (endX - startX);
int dy = (int) (endY - startY);
if (Math.abs(dx) + 50 > Math.abs(dy)) {
} else {
// 上下滑动,需要拦截
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
}
return handled | super.dispatchTouchEvent(ev);
}
protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
synchronized (HorizontalListView.this) {
mScroller.fling(mNextX, 0, (int) -velocityX, 0, 0, mMaxX, 0, 0);
}
requestLayout();
return true;
}
protected boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
return true;
}
private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return HorizontalListView.this.onDown(e);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
synchronized (HorizontalListView.this) {
mNextX += (int) distanceX;
}
requestLayout();
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if (mOnItemClicked != null) {
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
if (mOnItemSelected != null) {
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
return true;
}
@Override
public void onLongPress(MotionEvent e) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if (mOnItemLongClicked != null) {
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
}
private boolean isEventWithinView(MotionEvent e, View child) {
Rect viewRect = new Rect();
int[] childPosition = new int[2];
child.getLocationOnScreen(childPosition);
int left = childPosition[0];
int right = left + child.getWidth();
int top = childPosition[1];
int bottom = top + child.getHeight();
viewRect.set(left, top, right, bottom);
return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
}
};
//解决滑动和点击冲突问题
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = ev.getX();
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
float endX = ev.getX();
float endY = ev.getY();
float dx = endX - startX;
float dy = endY - startY;
if (Math.abs(dx) - 10 > Math.abs(dy)) {
return true;
} else if (Math.abs(dx) < Math.abs(dy) - 10) {
return true;
}
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
}
在xml文件中使用
<com.example.study1.customView.HorizontalListView
android:id="@+id/horizontal_hr_test"
android:layout_width="match_parent"
android:layout_height="100dp">
</com.example.study1.customView.HorizontalListView>
java设置自定义适配器
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.study1.R;
import com.example.study1.customView.HorizontalListView;
import java.util.ArrayList;
import java.util.List;
public class HorizontalListViewTest extends AppCompatActivity {
private HorizontalListView mHorizontalHrTest;
private List<String> names;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_horizontal_list_view_test);
initView();
names = new ArrayList<>();
names.add("张三");
names.add("李四");
names.add("王五");
names.add("张三");
names.add("李四");
names.add("王五");
names.add("张三");
names.add("李四");
names.add("王五");
names.add("张三");
names.add("李四");
names.add("王五");
AdapterHlistviewTestAdapter adapterHlistviewTestAdapter = new AdapterHlistviewTestAdapter(names, getApplicationContext());
mHorizontalHrTest.setAdapter(adapterHlistviewTestAdapter);
}
private void initView() {
mHorizontalHrTest = (HorizontalListView) findViewById(R.id.horizontal_hr_test);
}
public class AdapterHlistviewTestAdapter extends BaseAdapter {
List<String> listBeans;
Context context;
public AdapterHlistviewTestAdapter (List<String> listBeans, Context context){
this.listBeans = listBeans;
this.context = context;
}
@Override
public int getCount() {
return listBeans.size();
}
@Override
public String getItem(int position) {
return listBeans.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_hlistview_test, null);
convertView.setTag(new ViewHolder(convertView));
}
initializeViews((String)getItem(position), (ViewHolder) convertView.getTag());
return convertView;
}
private void initializeViews(final String object, final ViewHolder holder) {
//TODO implement
try {
//此处编写你的逻辑代码
holder.adapterHlistViewTvTest.setText(object);
}catch (Exception e){
}
}
protected class ViewHolder {
private ImageView adapterHlistViewIvTest;
private TextView adapterHlistViewTvTest;
public ViewHolder(View view) {
adapterHlistViewIvTest = (ImageView) view.findViewById(R.id.adapter_hlist_view_iv_test);
adapterHlistViewTvTest = (TextView) view.findViewById(R.id.adapter_hlist_view_tv_test);
}
}
}
}
4、网格列表GridView的使用
4.1 属性
4.2 关联BaseAdapter适配器
4.3 事件
- setOnItemClickListener: 点击事件
<!--
numColumn: 列数
verticalSpacing: 垂直空格
-->
<GridView
android:numColumns="3"
android:id="@+id/grid_view_test"
android:verticalSpacing="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</GridView>
绑定 相应的适配器/设置相应的事件即可
public class GridViewTest extends AppCompatActivity {
private GridView mGridViewTest;
private List<String> names;
private AdapterHlistviewTestAdapter listViewTestAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid_view_test);
initView();
setView();
}
private void setView() {
}
private void initView() {
mGridViewTest = (GridView) findViewById(R.id.grid_view_test);
names = new ArrayList<>();
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
names.add("张三");
listViewTestAdapter = new AdapterHlistviewTestAdapter(names, getApplication());
mGridViewTest.setAdapter(listViewTestAdapter);
}
public class AdapterHlistviewTestAdapter extends BaseAdapter {
List<String> listBeans;
Context context;
public AdapterHlistviewTestAdapter ( List<String> listBeans, Context context){
this.listBeans = listBeans;
this.context = context;
}
@Override
public int getCount() {
return listBeans.size();
}
@Override
public String getItem(int position) {
return listBeans.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_hlistview_test, null);
convertView.setTag(new ViewHolder(convertView));
}
initializeViews((String)getItem(position), (ViewHolder) convertView.getTag());
return convertView;
}
private void initializeViews(final String object, final ViewHolder holder) {
//TODO implement
try {
//此处编写你的逻辑代码
holder.adapterHlistViewTvTest.setText(object);
}catch (Exception e){
}
}
protected class ViewHolder {
private TextView adapterHlistViewTvTest;
public ViewHolder(View view) {
adapterHlistViewTvTest = (TextView) view.findViewById(R.id.adapter_hlist_view_tv_test);
}
}
}
}
5、静态进度条xxxBar的使用
5.1 SeekBar: 拖动条
5.1.1 属性
<!--
拖动条
max: 最大值
progress: 当前值
secondaryProgress: 缓存条
-->
<SeekBar
android:id="@+id/bar_seek_test"
android:layout_width="match_parent"
android:max="100"
android:progress="10"
android:layout_height="wrap_content"
android:secondaryProgress="20"/>
5.1.2 事件
private SeekBar mBarSeekTest;
private String logTag = "logStatus";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seek_progress_rating_bar);
initView();
setView();
}
private void setView() {
// 监听事件
mBarSeekTest.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
// 进度条改变事件
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
Log.d(logTag, "seekBar发生改变了");
}
// 开始触碰
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.d(logTag, "seekBar触碰了");
}
// 停止触碰
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d(logTag, "seekBar停止触碰了");
}
});
}
private void initView() {
mBarSeekTest = (SeekBar) findViewById(R.id.bar_seek_test);
}
5.2 ProgressBar: 加载条
5.2.1 属性
<ProgressBar
android:id="@+id/bar_pro_test"
android:max="100"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
5.2.2 方法
public class SeekProgressRatingBar extends AppCompatActivity implements View.OnClickListener {
private SeekBar mBarSeekTest;
private String logTag = "logStatus";
private ProgressBar mBarProTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seek_progress_rating_bar);
initView();
setView();
}
private void setView() {
// 监听事件
mBarSeekTest.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
// 进度条改变事件
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
Log.d(logTag, "seekBar发生改变了");
// View.setVisibility(View.GONE) 控件隐藏
// View.setVisibility(View.VISIBLE) 控件展示
if(seekBar.getProgress() == 100){
mBarProTest.setVisibility(View.GONE);
}else{
mBarProTest.setVisibility(View.VISIBLE);
}
}
// 开始触碰
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
Log.d(logTag, "seekBar触碰了");
}
// 停止触碰
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.d(logTag, "seekBar停止触碰了");
}
});
}
private void initView() {
mBarSeekTest = (SeekBar) findViewById(R.id.bar_seek_test);
mBarProTest = (ProgressBar) findViewById(R.id.bar_pro_test);
}
@Override
public void onClick(View view) {
switch (view.getId()){
default:
break;
}
}
}
5.3 RatingBar: 评价条
5.2.1 属性
<RatingBar
android:numStars="5"
android:rating="3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:secondaryProgress="20" />
5.2.2 方法
mBarRatingTest.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
Log.d(logTag, ""+ratingBar.getProgress());
Toast.makeText(getApplicationContext(), "当前评价"+ratingBar.getProgress(), Toast.LENGTH_SHORT).show();
}
});
5、动态进度条xxxBar的使用
5.1 多种线程方法实现
5.2 Handler+Thread: 线程(定时器/监听器)
- 创建线程类
// 动态线程进度条
Thread thread = new Thread(){
@Override
public void run() {
while (true){
try {
sleep(1000);
// 逻辑代码
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
5.2.1 通过Handler主线程ui机制
子线程使用Handler对主线程中的UI组件进行修改
- 解析
通过Message传递消息,然后Handler接受消息并修改组件
- 发送消息模版
Handle
Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what){
case MESSAGE_TEST1:
// 传入接受的是test1的消息,并修改主线程的UI
mBarSeekTest.setProgress(progress);
mBarTvTest.setText(progress+"%");
break;
}
}
};
Thread
// 通过handle与主线程UI进行通信
Message message = new Message();
message.what = MESSAGE_TEST1;
handler.sendMessage(message);
注意
在线程中每次开始都要重新new一下Message对象
6、网页显示WebView的使用(类似于iframe)
6.1 权限
开启网络权限
6.2 应用领域
- app显示网页
- 简单浏览器
- 前端app
6.3 方法
6.3.1 配置
6.3.1 使用
<WebView
android:id="@+id/web_view_test"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
实例1(通过url获得webView)
public class WebViewTest extends AppCompatActivity {
private WebView mWebViewTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view_test);
initView();
setView();
}
private void initWebView(){
// 设置可操作
mWebViewTest.setWebViewClient(new WebViewClient());
// 获得浏览器设置
WebSettings webSettings = mWebViewTest.getSettings();
// 将图片设置为相应大小
webSettings.setUseWideViewPort(true);
}
private void setView() {
mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
// 初始化WebView
initWebView();
}
private void initView() {
mWebViewTest = (WebView) findViewById(R.id.web_view_test);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK){
// 如果当前界面可以后退
if(mWebViewTest.canGoBack()){
mWebViewTest.goBack();
return false;
}
}
return super.onKeyDown(keyCode, event);
}
}
实例2(通过html代码获得webView)
private void setView() {
// mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
String htmlData = "<h2>1111111</h2>";
mWebViewTest.loadDataWithBaseURL("about:blank", htmlData,"text/html", "utf-8", null );
// 初始化WebView
initWebView();
}
6.3.2 监听
实例3(监听加载完成事件)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".activitys.WebViewTest">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/web_view_pro_bar"
android:layout_width="match_parent"
android:layout_height="500dp" />
<TextView
android:id="@+id/web_view_tv_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="60dp"
android:gravity="center"
android:layout_centerInParent="true"
android:text="0%">
</TextView>
</RelativeLayout>
<WebView
android:id="@+id/web_view_test"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
public class WebViewTest extends AppCompatActivity {
private WebView mWebViewTest;
private ProgressBar mWebViewProBar;
private TextView mWebViewTvTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view_test);
initView();
setView();
}
private void initWebView() {
// 设置可操作
mWebViewTest.setWebViewClient(new WebViewClient());
// 获得浏览器设置
WebSettings webSettings = mWebViewTest.getSettings();
// 将图片设置为相应大小
webSettings.setUseWideViewPort(true);
}
private void setView() {
mWebViewTest.loadUrl("https://www.58pic.com/?tid=1100857&utm_source=baidu&utm_medium=cpc&utm_campaign=%C9%E8%BC%C6-%BE%AB%C8%B7&utm_content=%CB%D8%B2%C4-%CD%A8%D3%C31&utm_term=%CD%BC%C6%AC&sdclkid=Asjpb5-pALoz15-N&renqun_youhua=2216851&bd_vid=7270136719499164176");
// 监听加载完成事件
mWebViewTest.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mWebViewProBar.setVisibility(View.GONE);
mWebViewTvTest.setVisibility(View.GONE);
mWebViewTest.setVisibility(View.VISIBLE);
}
});
mWebViewTest.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
if(newProgress < 100){
mWebViewProBar.setProgress(newProgress);
mWebViewTvTest.setText(newProgress+"%");
}else{
mWebViewProBar.setVisibility(View.GONE);
mWebViewTvTest.setVisibility(View.GONE);
mWebViewTest.setVisibility(View.VISIBLE);
}
}
});
// String htmlData = "<h2>1111111</h2>";
// mWebViewTest.loadDataWithBaseURL("about:blank", htmlData,"text/html", "utf-8", null );
// 初始化WebView
// initWebView();
}
private void initView() {
mWebViewTest = (WebView) findViewById(R.id.web_view_test);
mWebViewProBar = (ProgressBar) findViewById(R.id.web_view_pro_bar);
mWebViewTvTest = (TextView) findViewById(R.id.web_view_tv_test);
}
// 点击返回不退出程序
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// 如果当前界面可以后退
if (mWebViewTest.canGoBack()) {
mWebViewTest.goBack();
return false;
}
}
return super.onKeyDown(keyCode, event);
}
}
7、碎片界面Fragment的使用(类似于vue layout内部的界面)
7.1 简述
使用Fragment可以把屏幕分成几块,然后进行分组,进行一个模块化管理。Fragment不能够单独使用, 需要嵌套在Activity中使用,其生命周期也收到宿主Activity的生命周期影响
7.2 使用
7.2.1 步骤一: 准备一个碎片存放处(占位)
<LinearLayout
android:id="@+id/fm_layout_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
7.2.2 步骤二: 准备一个Fregment碎片界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".fragment.Fragment01">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="我是fragment01界面"/>
</LinearLayout>
public class Fragment01 extends Fragment {
private View view;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// fragment组装xml
view = inflater.inflate(R.layout.activity_fragment01,container, false);
return view;
}
}
7.2.2 步骤三: 替换占位
- 方法一: 链式替换<=>分步骤
// 链式替换
getSupportFragmentManager().beginTransaction().replace(R.id.fm_layout_test, new Fragment01()).commit();
- 方法二: 状态保持
8、轮播组件ViewPager的使用
8.1 使用范围
- 图片查看器
- 首页轮播图片
- 首页多页面(fragment)
- …
8.2 方法
- setCurrentItem: 跳转页面(第二个参数为false: 没有动画)
- setOffscreenPageLimit: 设置缓存界面个数
// 默认显示第一个
mViewPagerTest.setCurrentItem(1);
8.3 使用
8.3.1 准备数据
private void initView() {
mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
list = new ArrayList<>();
list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
list.add(LayoutInflater.from(getApplication()).inflate(R.layout.activity_button_test, null));
}
8.3.2 设置适配器(PagerAdapter)
private void setView() {
mViewPagerTest.setAdapter(new PagerAdapter() {
// 获得当前窗体的数量
@Override
public int getCount() {
return list.size();
}
// 判断是否是由对象生成的界面
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
// 从ViewGroup中移除当前view
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(list.get(position));
}
// 返回对象, 这个对象表明了PageAdapter装载了哪个对象到当前的界面当中,也是适配器的装载过程
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
mViewPagerTest.addView(list.get(position));
return list.get(position);
}
});
}
9、轮播组件ViewPager+Fragment+TabLayout的使用
9.1 三方插件: TabLayout
implementation 'com.android.support:design:27.1.1'
9.2 ViewPage+Fragment
private void setView() {
// FragmentStatePagerAdapter 有缓存的作用,不需要在初始化view等操作,系统内部自动处理
mViewPagerTest.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
});
}
private void initView() {
mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
fragments = new ArrayList<>();
fragments.add(new Fragment01());
fragments.add(new Fragment02());
}
9.2 TabLayout+ ViewPage +Fragment
使用场景
- 主页
- 轮播图
- 引导界面
- …
9.2.1 xml引入TabLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".activitys.ViewPageTest">
<com.google.android.material.tabs.TabLayout
android:id="@+id/view_pager_tl_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager_test"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
9.2.2 java控制tab切换
public class ViewPageTest extends AppCompatActivity {
private ViewPager mViewPagerTest;
private List<Fragment> fragments;
private List<String> titles;
private TabLayout mViewPagerTlTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_page_test);
initView();
setView();
}
private void setView() {
// FragmentStatePagerAdapter 有缓存的作用,不需要在初始化view等操作,系统内部自动处理-兼容以前那种方式实现的懒加载
mViewPagerTest.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager(), FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
});
// 将tabLayout与viewPager做关联
mViewPagerTlTest.setupWithViewPager(mViewPagerTest);
}
private void initView() {
mViewPagerTest = (ViewPager) findViewById(R.id.view_pager_test);
fragments = new ArrayList<>();
fragments.add(new Fragment01());
fragments.add(new Fragment02());
mViewPagerTlTest = (TabLayout) findViewById(R.id.view_pager_tl_test);
titles = new ArrayList<>();
titles.add("第一个");
titles.add("第二个");
}
}
10、侧滑菜单栏 SlidingPaneLayout || DrawerLayout的使用
10.1 引入相应配置
// SlidingPaneLayout
implementation "androidx.slidingpanelayout:slidingpanelayout:1.1.0-beta01"
10.2 写入xml界面(写死内容区)
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sl_layout_test"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:background="#287777"
android:layout_gravity="start"
android:layout_width="240dp"
android:layout_height="match_parent">
</LinearLayout>
<LinearLayout
android:layout_gravity="right"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
通过layout_gravity判断是内容区还是列表区
layout_gravity: start 列表区
layout_gravity: right 内容区
10.2 写入xml界面(使用fragment)
<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sl_layout_test"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:background="#287777"
android:layout_gravity="start"
android:layout_width="240dp"
android:layout_height="match_parent">
</LinearLayout>
<LinearLayout
android:layout_gravity="right"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
通过layout_gravity判断是内容区还是列表区
layout_gravity: start 列表区
layout_gravity: right 内容区
10.3 属性
- 属性
- 设置透明颜色
mSlLayoutTest.setSliderFadeColor(Color.TRANSPARENT);
- 打开/关闭-api
mSlLayoutTest.openPane();
- 设置显示样式
// 获得滑动的样式监听 mSlLayoutTest.setPanelSlideListener(new SlidingPaneLayout.PanelSlideListener() { @Override public void onPanelSlide(@NonNull View panel, float slideOffset) { Log.d("SLDrawerLayout", slideOffset+"------"); //覆盖样式 //panel:移动的View,slideOffset:移动的值 //覆盖界面 leftView.setScaleX(0.8f + 0.2f * slideOffset);//0.8~1//设置X偏移 leftView.setScaleY(0.8f + 0.2f * slideOffset);//0.8~1//设置y偏移 leftView.setAlpha(0.8f + 0.2f * slideOffset);//0.8~1//设置透明度 //主界面 panel.setScaleX(1 - 0.2f * slideOffset);//1~0.8 //设置X偏移 panel.setScaleY(1 - 0.2f * slideOffset);//1~0.8//设置y偏移 panel.setAlpha(1 - 0.8f * slideOffset);//1~0.8//设置透明度 } @Override public void onPanelOpened(@NonNull View panel) { } @Override public void onPanelClosed(@NonNull View panel) { } });
- 设置透明颜色
10.4 DrawrLayout
10、下拉刷新SwipeRefreshLayout的使用
10.1 条件(类似于vue的template)
只能有一个根元素
10.2 使用
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activitys.SwipeRefreshLayoutTest">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:gravity="center"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="刷新"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
10.3 方法属性
private void setView() {
// 设置不可滑动
mSwipeRefreshTest.setEnabled(false);
// 出现加载动画
mSwipeRefreshTest.setRefreshing(true);
// 设置刷新框的颜色
mSwipeRefreshTest.setColorSchemeResources(R.color.myColor2,R.color.myColor);
new Thread(){
@Override
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取数据成功/失败
mSwipeRefreshTest.setRefreshing(false);
}
}.start();
// 监听下拉事件
mSwipeRefreshTest.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
// 下拉触发
// 请求接口获取下拉数据
new Thread(){
@Override
public void run() {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 获取数据成功/失败
mSwipeRefreshTest.setRefreshing(false);
}
}.start();
}
});
}