效果圖1.gif
效果圖2.gif
實現(xiàn)思路
需求是在無網(wǎng)絡(luò)的時候顯示特定的頁面,想到要替換頁面的地方,大多都是recyclerview或者第三方recyclerview這種需要顯示數(shù)據(jù)的地方,因此決定替換掉頁面中所有的recyclerview為無網(wǎng)絡(luò)頁面
實現(xiàn)過程
- 在BaseActivity中,當(dāng)加載布局成功以后,通過id找到要替換的view,通過
indexOfChild()
方法,找到要替換的view的位置,再通過remove和add view來實現(xiàn),因為是在base替換,而且使用的是findviewById,這樣子就省去了考慮fragment中的view,局限性是要替換的view的命名必須要統(tǒng)一
2 點擊按鈕重新請求數(shù)據(jù),需要重新刷新數(shù)據(jù),因此使用了無網(wǎng)絡(luò)頁面的act需要重寫base的刷新數(shù)據(jù)方法,去重新請求數(shù)據(jù)。
優(yōu)缺點
因為只在base中替換,因此要替換的view,id名需要一致,對比通過decorview拿到content之后遍歷所有控件獲取到要替換的view的方法效率更高,而且省去了考慮fragment的情況,通過findViewById()
方法可以直接獲取到fragment中需要替換的recyclerview。
代碼實現(xiàn)
- 在加載布局成功初始化無網(wǎng)絡(luò)頁面
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
initNoNetView(R.id.id_xrv,R.id.rv);
}
}
- 需要一個工具類用來獲取網(wǎng)絡(luò)狀態(tài)
/**
* 判斷網(wǎng)絡(luò)是否連接
*
* @param context
* @return
*/
public static boolean isConnected(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (null != connectivity) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (null != info && info.isConnected()) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
- 初始化無網(wǎng)絡(luò)頁面,定義一個不定長的view的id組成的數(shù)組,參數(shù)為需要替換的view的共同的id,可以為多個,會替換第一個找到的不為null的view。
private void initNoNetView(int ...ids) {
if (!OkHttpUtil.isConnected(BaseActivity.this) && !haveShowNetView) {
final List<View> viewList = new ArrayList<>();
//通過id獲取view
for (int id : ids) {
viewList.add(findViewById(id));
}
//實現(xiàn)自己的無網(wǎng)絡(luò)頁面
final View noNetView = View.inflate(BaseActivity.this, R.layout.layout_no_net, null);
noNetView.findViewById(R.id.btn_try).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!OkHttpUtil.isConnected(BaseActivity.this)) {
T.showShort(BaseActivity.this, "沒有獲取到網(wǎng)絡(luò),請重試...");
return;
}
//切換到有網(wǎng)絡(luò)頁面
showHaveNetView(viewList,noNetView);
}
});
//切換到無網(wǎng)絡(luò)頁面
showNoNetView(viewList,noNetView);
}
}
- 頁面切換
private void showHaveNetView(List<View> viewList, View noNetView) {
for (View view : viewList) {
if (view==null){
continue;
}
haveShowNetView = false;
transView(noNetView, view);
onReNetRefreshData();
break;
}
}
private void showNoNetView(List<View> viewList, View noNetView) {
for (View view : viewList) {
if (view==null){
continue;
}
haveShowNetView = true;
transView(view, noNetView);
break;
}
}
protected void transView(final View defaultView, View replaceView) {
final int index = ((ViewGroup) defaultView.getParent()).indexOfChild(defaultView);
ViewGroup.LayoutParams params = defaultView.getLayoutParams();
ViewGroup parent = (ViewGroup) defaultView.getParent();
parent.removeView(defaultView);
parent.addView(replaceView, index, params);
}
- 點擊按鈕顯示有網(wǎng)絡(luò)頁面的時候通知頁面更新數(shù)據(jù),BaseAct為空實現(xiàn),需要更新數(shù)據(jù)的頁面重寫
onReNetRefreshData()
方法。
public void onReNetRefreshData() {
}
整體代碼
private boolean haveShowNetView = false;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
initNoNetView(R.id.id_xrv,R.id.rv);
}
}
private void initNoNetView(int ...ids) {
if (!OkHttpUtil.isConnected(BaseActivity.this) && !haveShowNetView) {
final List<View> viewList = new ArrayList<>();
//通過id獲取view
for (int id : ids) {
viewList.add(findViewById(id));
}
//實現(xiàn)自己的無網(wǎng)絡(luò)頁面
final View noNetView = View.inflate(BaseActivity.this, R.layout.layout_no_net, null);
noNetView.findViewById(R.id.btn_try).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!OkHttpUtil.isConnected(BaseActivity.this)) {
T.showShort(BaseActivity.this, "沒有獲取到網(wǎng)絡(luò),請重試...");
return;
}
//切換到有網(wǎng)絡(luò)頁面
showHaveNetView(viewList,noNetView);
}
});
//切換到無網(wǎng)絡(luò)頁面
showNoNetView(viewList,noNetView);
}
}
private void showHaveNetView(List<View> viewList, View noNetView) {
for (View view : viewList) {
if (view==null){
continue;
}
haveShowNetView = false;
transView(noNetView, view);
onReNetRefreshData();
break;
}
}
private void showNoNetView(List<View> viewList, View noNetView) {
for (View view : viewList) {
if (view==null){
continue;
}
haveShowNetView = true;
transView(view, noNetView);
break;
}
}
public void onReNetRefreshData() {
}
protected void transView(final View defaultView, View replaceView) {
final int index = ((ViewGroup) defaultView.getParent()).indexOfChild(defaultView);
ViewGroup.LayoutParams params = defaultView.getLayoutParams();
ViewGroup parent = (ViewGroup) defaultView.getParent();
parent.removeView(defaultView);
parent.addView(replaceView, index, params);
}