一,概述
经常我们刷新listview的时候,正常情况下会有数据,我们会按照正常情况让他展示数据。当没有数据的时候我们会用setemptyview方法。可是当我们遇到加载失败的时候怎么办,没有网络的时候怎么。这时候我们就必须自己根据需求来统一定义我们的内容界面,通常情况下。会有以下几种状态包括无数据、加载异常、正在加载、数据正常及全部不显示(根据需求自己定义的一个界面)
二,分析
接下来,我们就来上码
/**
* 不同状态的显示站位图(包括无数据,加载异常,正在加载,数据正常以及全部不显示5种状态)
*/
public class StatusSwitchLayout extends RelativeLayout {
private View vContentView;
private LinearLayout vRequestLayout;
private LinearLayout vFailureLayout;
private LinearLayout vNoDataLayout;
private ImageView vRequestImg;
private ImageView vFailureImg;
private ImageView vNoDataImg;
private Button vNoDataBtn;
public StatusSwitchLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initWithContext(context);
}
public StatusSwitchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initWithContext(context);
}
public StatusSwitchLayout(Context context) {
super(context);
initWithContext(context);
}
private void initWithContext(Context context){
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.status_switch_layout, this);
vRequestLayout = (LinearLayout)findViewById(R.id.request_layout);
vFailureLayout = (LinearLayout)findViewById(R.id.loading_failure_layout);
vNoDataLayout = (LinearLayout)findViewById(R.id.no_data_layout);
vRequestImg = (ImageView)findViewById(R.id.request_loading_img);
vFailureImg = (ImageView)findViewById(R.id.loading_failure_img);
vNoDataImg = (ImageView)findViewById(R.id.no_data_img);
vNoDataBtn = (Button)findViewById(R.id.other_operate_button);
}
public View getContentView() {
return vContentView;
}
/**
* 设置content layout 便于统一控制显示哪个layout
* @param vContentView
*/
public void setContentView(View vContentView) {
this.vContentView = vContentView;
}
public LinearLayout getRequestLayout() {
return vRequestLayout;
}
public LinearLayout getFailureLayout() {
return vFailureLayout;
}
public LinearLayout getNoDataLayout() {
return vNoDataLayout;
}
public ImageView getRequestImg() {
return vRequestImg;
}
public ImageView getFailureImg() {
return vFailureImg;
}
public ImageView getNoDataImg() {
return vNoDataImg;
}
public Button getNoDataBtn() {
return vNoDataBtn;
}
public void setRequestImgRes(int resId){
vRequestImg.setImageResource(resId);
}
public void setFailureImgRes(int resId){
vFailureImg.setImageResource(resId);
}
public void setNoDataImgRes(int resId){
vNoDataImg.setImageResource(resId);
}
public void setNoDataBtnBg(int resId){
vNoDataBtn.setBackgroundResource(resId);
}
public void showContentLayout(){
showWhichLayout(0);
}
public void showNoDataLayout(){
showWhichLayout(1);
}
public void showRequestLayout(){
showWhichLayout(2);
}
public void showFailureLayout(){
showWhichLayout(3);
}
public void dismissAll(){
showWhichLayout(4);
}
/**
* 0.代表显示content layout,1.代表显示无数据layout,2.代表显示请求layout,3.代表显示失败layout, 4.代表均不显示(预留显示其他可能的布�?)
* @param index
*/
private void showWhichLayout(int index){
switch (index) {
case 0:
if(null != vContentView && vContentView.getVisibility() == View.GONE){
showView(vContentView);
}
if(vNoDataLayout.getVisibility() == View.VISIBLE){
dismissView(vNoDataLayout);
}
if(vRequestLayout.getVisibility() == View.VISIBLE){
dismissView(vRequestLayout);
}
if(vFailureLayout.getVisibility() == View.VISIBLE){
dismissView(vFailureLayout);
}
break;
case 1:
if(null != vContentView && vContentView.getVisibility() == View.VISIBLE){
dismissView(vContentView);
}
if(vNoDataLayout.getVisibility() == View.GONE){
showView(vNoDataLayout);
}
if(vRequestLayout.getVisibility() == View.VISIBLE){
dismissView(vRequestLayout);
}
if(vFailureLayout.getVisibility() == View.VISIBLE){
dismissView(vFailureLayout);
}
break;
case 2:
if(null != vContentView && vContentView.getVisibility() == View.VISIBLE){
dismissView(vContentView);
}
if(vNoDataLayout.getVisibility() == View.VISIBLE){
dismissView(vNoDataLayout);
}
if(vRequestLayout.getVisibility() == View.GONE){
showView(vRequestLayout);
}
if(vFailureLayout.getVisibility() == View.VISIBLE){
dismissView(vFailureLayout);
}
break;
case 3:
if(null != vContentView && vContentView.getVisibility() == View.VISIBLE){
dismissView(vContentView);
}
if(vNoDataLayout.getVisibility() == View.VISIBLE){
dismissView(vNoDataLayout);
}
if(vRequestLayout.getVisibility() == View.VISIBLE){
dismissView(vRequestLayout);
}
if(vFailureLayout.getVisibility() == View.GONE){
showView(vFailureLayout);
}
break;
case 4:
if(null != vContentView && vContentView.getVisibility() == View.VISIBLE){
dismissView(vContentView);
}
if(vNoDataLayout.getVisibility() == View.VISIBLE){
dismissView(vNoDataLayout);
}
if(vRequestLayout.getVisibility() == View.VISIBLE){
dismissView(vRequestLayout);
}
if(vFailureLayout.getVisibility() == View.VISIBLE){
dismissView(vFailureLayout);
}
break;
default:
break;
}
}
private void showView(View view){
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate()
.alpha(1f)
.setDuration(300)
.setListener(null);
}
private void dismissView(final View view){
view.setVisibility(View.GONE);
// view.animate()
// .alpha(0f)
// .setDuration(300)
// .setListener(new AnimatorListenerAdapter() {
// @Override
// public void onAnimationEnd(Animator animation) {
//
// }
// });
}
}
这里逻辑很简单,大家看下代码就知道,其实就是自定义一个新的共有界面。根据逻辑做出判断就可以了。当我们定义好这个自定义控件,我们会在布局文件里先定义好,如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.nanjing.test.status.MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.handmark.pulltorefresh.library.PullToRefreshListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<include
layout="@layout/status_layout"/>
</RelativeLayout>
</RelativeLayout>
这里面的incude就是包含我们定义的控件。然后在activity里正常调用就可以了
public class MainActivity extends AppCompatActivity {
//可以是各种view
private PullToRefreshListView vLv;
//占位状态
private StatusSwitchLayout vstatues;
//
private List<String> mdata;
private MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initClick();
}
private void initView() {
vLv=(PullToRefreshListView)findViewById(R.id.listview);
vstatues=(StatusSwitchLayout)findViewById(R.id.status_layout);
//将view加载到状态里面去
vstatues.setContentView(vLv);
vstatues.getNoDataBtn().setText("没有数据");
}
private void initData() {
mdata=new ArrayList<>();
for(int i=0;i<20;i++){
mdata.add("今天天气不错"+i);
}
adapter=new MyAdapter(this,mdata);
vLv.setAdapter(adapter);
vstatues.showContentLayout();
//网络状态
if(!isNetworkConnected(this)){
vstatues.showFailureLayout();
}
}
private void initClick() {
vLv.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener2<ListView>() {
@Override
public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
// 模拟无网络的时候,加载失败的时候(当打开网络。可以点击就有数据了)。及正常状态的时候
// vLv.postDelayed(new Runnable() {
// @Override
// public void run() {
// initData();
// mdata.add("注意这里添加了一条数据。点击刷新会在数据的末尾加上这句");
// adapter.notifyDataSetChanged();
// vLv.onRefreshComplete();
// }
// }, 1000);
// 模拟没有数据
initData();
mdata=null;
vstatues.showNoDataLayout();
}
@Override
public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
}
});
vstatues.getFailureLayout().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
vstatues.getRequestLayout();
initData();
}
});
}
private class MyAdapter extends BaseAdapter{
private Context mcontext;
private List<String> mdata;
public MyAdapter(Context mcontext,List<String> mdata){
this.mcontext=mcontext;
this.mdata=mdata;
}
@Override
public int getCount() {
return mdata.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Object getItem(int position) {
return mdata.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView= LayoutInflater.from(mcontext).inflate(R.layout.item,null);
TextView tv=(TextView)convertView.findViewById(R.id.tv);
tv.setText(mdata.get(position).toString());
return convertView;
}
}
//判断是否有网络连接
public boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
}
小编只是单纯的用这个控件展示了下。供大家参考,若使用到代码中,还要与网络请求做好数据的处理,稍微改动下就可以使用
三,效果展示
效果入上图所示。自我感觉还可以。哈哈,由于小编水平有限。如有不当之处,还望不吝赐教,谢谢
代码资源
资源在这