利用觀察者(Observer)和被觀察者(Observable)實現監聽操作
阿新 • • 發佈:2019-01-05
老規矩上圖:
第一步:上佈局檢視只貼一部分
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f6534c"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height ="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text ="總財富"
android:textColor="#fcc7c6" />
<!--註冊checkBox為被觀察者-->
<com.example.hxl.observerdemo.CheckBoxObservable
android:id="@+id/checkBoxObservable"
android:layout_width="wrap_content"
android:layout_height ="wrap_content"
android:layout_marginLeft="5dp"
android:button="@drawable/bg_checkbox_sel" />
<!-- checkBox:xml中內部實現點選事件 android:button="@drawable/bg_checkbox_sel"-->
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/my_assert_total_account_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--讓總財富下的textView,成為觀察者-->
<com.example.hxl.observerdemo.TextViewObserver
android:id="@+id/my_assert_total_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:text="0.00"
android:textColor="#fccbca"
android:textSize="32sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:paddingBottom="2dp"
android:text="(交易確認中或暫無資產)"
android:textColor="#ffffff"
android:textSize="12sp" />
</LinearLayout>
<ImageView
android:id="@+id/total_account_hider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="20dp"
android:src="@drawable/wealth_hidden"
android:visibility="invisible" />
</RelativeLayout>
</LinearLayout>
第二步:被觀察者
/**
* 實現觀察者模式的被觀察者
* 讓checkBox成為被觀察者
*/
public class CheckBoxObservable extends CheckBox implements CompoundButton.OnCheckedChangeListener{
private ObservableInner mObservable;
public CheckBoxObservable(Context context) {
super(context);
init();
}
public CheckBoxObservable(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CheckBoxObservable(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void hide() {
// 狀態改變 ,資料改變
setChanged();
//傳送資訊告訴觀察者,只有為真時,才會呼叫觀察者的update方法
notifyObservers(true);
}
private void show() {
setChanged(); // 狀態改變,必須呼叫
notifyObservers(false);
}
//初始化操作
public void init() {
//建立被觀察者
mObservable = new ObservableInner();
//設定被觀察者狀態改變監聽
setOnCheckedChangeListener(this);
}
//新增觀察者
public void addObserver(Observer observer){
mObservable.addObserver(observer);
}
//刪除某一個具體的觀察者
public void deleteObserver(Observer observer) {
mObservable.deleteObserver(observer);
}
//刪除所有的觀察者
public void deleteObservers() {
mObservable.deleteObservers();
}
//返回列表中所有的新增觀察者
public int countObservers(){
return mObservable.countObservers();
}
//通知重新整理所有的觀察者
public void notifyObservers(){
mObservable.notifyObservers();
}
public void notifyObservers(Object data){
mObservable.notifyObservers(data);
}
public boolean hasChanged() {
return mObservable.hasChanged();
}
protected void setChanged() {
mObservable.setChanged();
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
hide();
} else {
show();
}
}
//被觀察者(Observable) 觀察者(Observer)
private class ObservableInner extends Observable {
//自定義setChange方法,實現調系統方法
public void setChanged() {
super.setChanged();
}
}
}
第三步:觀察者
/**
* 實現觀察者模式的觀察者
* 讓text實現成為觀察者
*Observer接收到通知的順序是越晚加入列表的越先通知。
*/
public class TextViewObserver extends TextView implements Observer{
private static final String DEFAULT_HIDER = "******";
private String mOrignalContent = "";
//設定隱藏的內容
private String mHiderContent = DEFAULT_HIDER;
//是否隱藏
private boolean mIsHideContent = false;
private OnShownListener mOnShownListener;
private OnHiderListener mOnHiderListener;
public TextViewObserver(Context context) {
super(context);
mOrignalContent = getText().toString();
}
public TextViewObserver(Context context, AttributeSet attrs) {
super(context, attrs);
mOrignalContent = getText().toString();
}
public TextViewObserver(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mOrignalContent = getText().toString();
}
//接收到被觀察者的訊號後,開始執行具體操作
@Override
public void update(Observable o, Object arg) {
mIsHideContent = (boolean)arg;
if (mIsHideContent) {
setText(mHiderContent);
if (mOnHiderListener != null) {
//回撥方法,用於銅幣狀態控制
mOnHiderListener.onHider();
}
} else {
setText(mOrignalContent);
if (mOnShownListener != null) {
mOnShownListener.onShown();
}
}
}
/**
* 注意:需要呼叫此方法才能實現隱藏效果,若直接呼叫setText()方法,則實現不了
* @param text
*/
public void setTextExtension(String text) {
mOrignalContent = String.valueOf(text);
if (!mIsHideContent) { // 非隱藏狀態下,更新內容
setText(mOrignalContent);
}
}
/**
* 注意:需要呼叫此方法才能實現隱藏效果,若直接呼叫setText()方法,則實現不了
* @param text
*/
public void setTextExtension(CharSequence text) {
mOrignalContent = String.valueOf(text);
if (!mIsHideContent) { // 非隱藏狀態下,更新內容
setText(mOrignalContent);
}
}
public void setHiderContent(String mHiderContent) {
this.mHiderContent = mHiderContent;
}
public String getHiderContent() {
return this.mHiderContent;
}
public void setOnShownListener(OnShownListener onShownListener) {
this.mOnShownListener = onShownListener;
}
public void setOnHiderListener(OnHiderListener onHiderListener) {
this.mOnHiderListener = onHiderListener;
}
public interface OnShownListener {
public void onShown();
}
public interface OnHiderListener {
public void onHider();
}
}
第四步:主體部分實現
CheckBoxObservable checkBoxObservable;
TextViewObserver myAssertTotalAccount;
TextViewObserver regularInvestmentAccount;
TextViewObserver tongbaoAccount;
LinearLayout myAssertTotalAccountLayout;
ImageView totalAccountHider;
//新增觀察者
checkBoxObservable.addObserver(myAssertTotalAccount);
//觀察者設定隱藏監聽
myAssertTotalAccount.setOnHiderListener(new TextViewObserver.OnHiderListener() {
@Override
public void onHider() {
//此時不能設定為Gone,會引起佈局的變化
myAssertTotalAccountLayout.setVisibility(View.INVISIBLE);
//設定銅寶圖片狀態
totalAccountHider.setVisibility(View.VISIBLE);
}
});
//觀察者設定顯示監聽
myAssertTotalAccount.setOnShownListener(new TextViewObserver.OnShownListener() {
@Override
public void onShown() {
myAssertTotalAccountLayout.setVisibility(View.VISIBLE);
//此時不能設定為Gone,會引起佈局的變化
totalAccountHider.setVisibility(View.INVISIBLE);
}
});
//新增其他觀察者
checkBoxObservable.addObserver(regularInvestmentAccount);
checkBoxObservable.addObserver(tongbaoAccount);
checkBoxObservable.addObserver(myBalanceAccount);
最後別忘了:解除被觀察者和觀察者之間的繫結
@Override
public void onDestroyView() {
super.onDestroyView();
//解綁
ButterKnife.unbind(this);
if (checkBoxObservable != null) {
//解除觀察者
checkBoxObservable.deleteObservers();
}
}
附帶:CheckBox的button點選選擇
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/wealth_eye_close" android:state_checked="true"/>
<item android:drawable="@drawable/wealth_eye_open" android:state_checked="false"/>
</selector>
以上,就可以實現