在实际开发中,可能会遇到这个需求: 如果界面有很多输入框,在点击返回的时候,没有输入过文字就不弹提示框,反之就弹框提示用户需要保存草稿吗?/确定退出吗?
如果给每一个view 设置 监听器想必代码会冗余很多, 也不易于维护, 那么就想到了这个办法,直接贴代码吧:
package com.******.library.utils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
* Created by LiKang on 2017/4/7 18:53.
* email:15034671952@163.com
*/
public class ViewStateCheckUtil {
private HashMap<Integer, BaseState> oldStates;
private HashMap<Integer, BaseState> newStates;
private View checkView;
private String TAG = "ViewStateCheckUtil";
//被忽略统计的view ID 集合
private ArrayList<Integer> ignoreViewIds;
public ViewStateCheckUtil(View checkView, ArrayList<Integer> ignoreViewIds) {
this.checkView = checkView;
this.ignoreViewIds = ignoreViewIds;
}
public ViewStateCheckUtil(View checkView) {
this.checkView = checkView;
}
public void setCurrentState() {
oldStates = getHierarchyState();
}
private List<View> getAllChildViews(View view) {
List<View> allChildren = new ArrayList<>();
if (ignoreViewIds != null && ignoreViewIds.contains(view.getId()))
return allChildren;
if (view instanceof ViewGroup) {
ViewGroup vp = (ViewGroup) view;
for (int i = 0; i < vp.getChildCount(); i++) {
View viewChild = vp.getChildAt(i);
allChildren.add(viewChild);
allChildren.addAll(getAllChildViews(viewChild));
}
}
return allChildren;
}
public HashMap<Integer, BaseState> getHierarchyState() {
HashMap<Integer, BaseState> hierarchyState = new HashMap<>();
if (checkView == null) return hierarchyState;
if (checkView instanceof ViewGroup) {
List<View> allChildViews = getAllChildViews(checkView);
Logger.d(TAG, allChildViews.toString());
Logger.d(TAG, "allChildViews.size():" + allChildViews.size());
for (int i = 0; i < allChildViews.size(); i++) {
addViewState(hierarchyState, allChildViews.get(i));
}
} else {
addViewState(hierarchyState, checkView);
}
return hierarchyState;
}
private void addViewState(HashMap<Integer, BaseState> hierarchyState, View child) {
if (child.getId() == View.NO_ID)
return;
if (child instanceof CompoundButton) { //CompoundButton 也是 TextView 子类
CompoundButtonState state = new CompoundButtonState();
CompoundButton compoundButton = (CompoundButton) child;
state.setChecked(compoundButton.isChecked());
hierarchyState.put(child.getId(), state);
} else if (child instanceof TextView) {
TextViewState state = new TextViewState();
TextView textView = (TextView) child;
state.setText(textView.getText().toString());
hierarchyState.put(child.getId(), state);
}
}
public Boolean checkViewIsChanged() {
newStates = getHierarchyState();
if (oldStates == null)
return false;
Logger.d("checkViewIsChanged,newStates", newStates.toString());
Logger.d("checkViewIsChanged,oldStates", oldStates.toString());
Set<Integer> newKeySet = newStates.keySet();
Set<Integer> oldKeySet = oldStates.keySet();
Set<Integer> keySet = newKeySet.size() > oldKeySet.size() ? newKeySet : oldKeySet;
for (Integer viewId : keySet) {
BaseState newState = newStates.get(viewId);
BaseState oldState = oldStates.get(viewId);
Logger.d(TAG, "newState:" + newState);
Logger.d(TAG, "oldState:" + oldState);
if (!(newState + "").equals(oldState + "")) {
return true;
}
}
return false;
}
private class BaseState {
}
private class TextViewState extends BaseState {
String text;
String getText() {
return text;
}
void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "TextViewState{" +
"text=" + text +
'}';
}
}
private class CompoundButtonState extends BaseState {
boolean checked;
boolean isChecked() {
return checked;
}
void setChecked(boolean checked) {
this.checked = checked;
}
@Override
public String toString() {
return "CompoundButtonState{" +
"checked=" + checked +
'}';
}
}
//TODO other view states supplement
}
如何使用?代码很简单, 可能你已经知道使用方式了。
private ViewStateCheckUtil viewStateCheckUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.....
ArrayList<Integer> ignoreViewIds = new ArrayList<>();
ignoreViewIds.add(lvVideo.getId());//设置要忽略的view ;
viewStateCheckUtil = new ViewStateCheckUtil(mRootView, ignoreViewIds/*可以传null*/);
viewStateCheckUtil.setCurrentState();//在这里保存要统计view的状态
}
@Override
public void onBackPressed() {
finishNotify();
}
private void finishNotify() {
if (viewStateCheckUtil.checkViewIsChanged()) {
//弹框提示,是否要退出编辑
} else {
finish();
}
}
好了,到此结束了。。。