Android开发实现自定义新闻加载页面功能实例

本文实例讲述了Android开发实现自定义新闻加载页面功能。分享给大家供大家参考,具体如下:

一、概述:

1、效果演示:

2、说明:在新闻页面刚加载的时候,一般会出现五种状态

未知状态(STATE_UNKNOW)、空状态(STATE_EMPTY)、加载中(STATE_LOADING)、错误(STATE_ERROT)、成功(STATE_SUCCESS)

因为每个Detail页面都会出现,所以我们可以把他们封装成一个LoadPage的自定义view,可以复用

二、实现:

1、首先的定义三个布局,为什么是三个,因为unkonw与loading的页面可以使用同一个,而success的页面是加载数据的页面,这里不用定义

1)loading页面布局,只有一个进度条

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >
  <ProgressBar
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" />
</RelativeLayout>

2)空页面只有一张图片,显示没有数据

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >
  <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:src="@drawable/ic_empty_page" />
</RelativeLayout>

3)错误页面有一张错误图片与按钮,点击按钮重新加载数据

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >
  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center" >
    <ImageView
      android:id="@+id/page_iv"
      android:layout_width="100dp"
      android:layout_height="100dp"
      android:layout_centerHorizontal="true"
      android:scaleType="centerInside"
      android:src="@drawable/ic_error_page" />
    <Button
      android:id="@+id/page_bt"
      android:layout_width="wrap_content"
      android:layout_height="34dp"
      android:layout_below="@id/page_iv"
      android:layout_centerHorizontal="true"
      android:layout_marginTop="10dp"
      android:background="@drawable/btn_bg"
      android:ellipsize="end"
      android:paddingLeft="10dp"
      android:paddingRight="10dp"
      android:singleLine="true"
      android:text="@string/load_error"
      android:textColor="#ff717171"
      android:textSize="14dp" />
  </RelativeLayout>
</FrameLayout>

4、初始化控件

/**
* 初始化加载三种布局
*/
private void init() {
    mLoadingView = initView(R.layout.loadpage_loading);
    mEmptyView = initView(R.layout.loadpage_empty);
    mErrorView = initView(R.layout.loadpage_error);
    //如果发生错误,点击重新加载
    Button btnError = (Button) mErrorView.findViewById(R.id.page_bt);
    btnError.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        show();
      }
    });
    showPages();
}

5、全部代码:

/**
 * @描述 加载页面
 * @项目名称 App_Shop
 * @包名 com.android.shop.view
 * @类名 LoadingPage
 * @author chenlin
 * @date 2014年3月29日 下午8:49:39
 */
public abstract class LoadingPage extends FrameLayout {
  private final static int STATE_UNKNOW = 0;
  private final static int STATE_LOADING = 1;
  private final static int STATE_ERROT = 2;
  private final static int STATE_EMPTY = 3;
  private final static int STATE_SUCCESS = 4;
  // 不能使用静态的,
  private int currentState = STATE_UNKNOW;
  private View mLoadingView; // 加载
  private View mEmptyView; // 空页面
  private View mErrorView; // 网络错误
  private View mSuccessView; // 加载成功后的页面
  private Context mContext;
  /**
   * 定义枚举类型
   */
  public enum LoadResult {
    error(STATE_ERROT), empty(STATE_EMPTY), success(STATE_SUCCESS);
    int value;
    LoadResult(int value) {
      this.value = value;
    }
    public int getValue() {
      return value;
    }
  }
  public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext = context;
    init();
  }
  public LoadingPage(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }
  public LoadingPage(Context context) {
    this(context, null);
  }
  /**
   * 初始化加载三种布局
   */
  private void init() {
    mLoadingView = initView(R.layout.loadpage_loading);
    mEmptyView = initView(R.layout.loadpage_empty);
    mErrorView = initView(R.layout.loadpage_error);
    //如果发生错误,点击重新加载
    Button btnError = (Button) mErrorView.findViewById(R.id.page_bt);
    btnError.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        show();
      }
    });
    showPages();
  }
  public View initView(int resId) {
    View view = View.inflate(mContext, resId, null);
    if (view != null) {
      this.addView(view, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
      return view;
    }
    return null;
  }
  private void showPages() {
    //加载页面显示与不显示
    mLoadingView.setVisibility(currentState == STATE_UNKNOW || currentState == STATE_LOADING ? View.VISIBLE
        : View.GONE);
    //空页面
    mEmptyView.setVisibility(currentState == STATE_EMPTY ? View.VISIBLE : View.GONE);
    //错误页面显示
    mErrorView.setVisibility(currentState == STATE_ERROT ? View.VISIBLE : View.GONE);
    //如果数据加载成功了,
    if (currentState == STATE_SUCCESS) {
      if (mSuccessView == null) {
        //加载成功页面信息,成功后的页面就是新闻页面信息
        mSuccessView = createSuccessView();
        //添加页面到framelayout里
        addView(mSuccessView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
        mSuccessView.setVisibility(View.VISIBLE);
      }else {
        mSuccessView.setVisibility(View.GONE);
      }
    }
  }
  public void show() {
    if (currentState == STATE_EMPTY || currentState == STATE_ERROT) {
      currentState = STATE_LOADING;
    }
    // 请求服务器 获取服务器上数据 进行判断
    // 请求服务器 返回一个结果
    ThreadManager.getInstance().createLongPool().execute(new Runnable() {
      @Override
      public void run() {
        //从服务器加载数据,得到返回的状态信息
        final LoadResult result = loadFromServer();
        if (result != null) {
          Util.runOnUiThread(new Runnable() {
            @Override
            public void run() {
              currentState = result.getValue();
              //显示
              showPages();
            }
          });
        }
      }
    });
    showPages();
  }
  public abstract View createSuccessView();
  public abstract LoadResult loadFromServer();
}

三、使用:

/**
 * @描述     fragment
 * @项目名称   App_Shop
 * @包名     com.android.shop.fragment
 * @类名     BaseFragment
 * @author   chenlin
 * @date    2014年3月28日 下午10:33:59
 */
public abstract class BaseFragment<T> extends Fragment {
  private LoadingPage mLoadingPage;
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    if (mLoadingPage == null) {
      mLoadingPage = new LoadingPage(getActivity()){
        @Override
        public View createSuccessView() {
          return BaseFragment.this.createSuccessView();
        }
        @Override
        public LoadResult loadFromServer() {
          return BaseFragment.this.load();
        }
      };
    }else {
      ViewUtil.removeParent(mLoadingPage);
    }
    return mLoadingPage;
  }
  /***
   * 创建成功的界面
   * @return
   */
  public abstract View createSuccessView();
  /**
   * 从服务器得到结果吗
   * @return
   */
  protected abstract LoadResult load();
  /**
   * 显示加载页面
   */
  public void show(){
    if (mLoadingPage != null) {
      mLoadingPage.show();
    }
  }
  /**校验数据 */
  public LoadResult checkData(List<T> datas){
    if (datas == null) {
      return LoadResult.error;
    }else {
      if (datas.size() == 0) {
        return LoadResult.empty;
      }else {
        return LoadResult.success;
      }
    }
  }
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android调试技巧与常见问题解决方法汇总》、《Android基本组件用法总结》、《Android视图View技巧总结》、《Android布局layout技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

时间: 2017-10-15

Android自定义加载loading view动画组件

在github上找的一个有点酷炫的loading动画https://github.com/Fichardu/CircleProgress 我写写使用步骤 自定义view(CircleProgress )的代码 package com.hysmarthotel.view; import com.hysmarthotel.roomcontrol.R; import com.hysmarthotel.util.EaseInOutCubicInterpolator; import android.ani

加载页面遮挡耗时操作任务页面--第三方开源之AndroidProgressLayout

AndroidProgressLayout实现为界面添加圆形进度条.调用setprogress()方法显示和隐藏进度条 在Android的开发中,往往有这种需求,比如一个耗时的操作,联网获取网络图片.内容,数据库耗时读写等等,在此耗时操作过程中,开发者也许不希望用户再进行其他操作(其他操作可能会引起逻辑混乱),而此时需要给用户一个额外的加载页面遮挡住主逻辑代码的运行,待主页面的耗时操作完成后,自动消失这样加载过度页面,恢复出正常应该显示的页面. 举个实际的例子,如代码使用Android WebV

Android自定义加载控件实现数据加载动画

本文实例为大家分享了Android自定义加载控件,第一次小人跑动的加载效果眼前一亮,相比传统的PrograssBar高大上不止一点,于是走起,自定义了控件LoadingView去实现动态效果,可直接在xml中使用,具体实现如下 package com.*****.*****.widget; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.util.

Android自定义下拉刷新上拉加载

本文实例为大家分享了Android自定义下拉刷新上拉加载的具体实现步骤,供大家参考,具体内容如下 实现的方式是SwipeRefreshLayout + RecyclerView 的VIewType 首先看效果: 总的思路: 布局文件 <android.support.v4.widget.SwipeRefreshLayout android:layout_marginTop="?attr/actionBarSize" android:id="@+id/one_refres

Android自定义Dialog实现文字动态加载效果

之前在技术问答上面看到一个提问 "加载中-" 后面三个点是动态的,这么一个效果实现.想来想去,好像没想到好的处理方式. 尝试了一下,以一个最笨的方式实现了.先来看一下效果 : 我是通过自定义一个Dialog,加载中的效果,是在Dialog内部实现的,进度还是从Activity里面控制的. 下面是Dialog实现类: public class CustomDialog extends AlertDialog { public CustomDialog(Context context) {

Android中替换WebView加载网页失败时的页面

我们用webView去请求一个网页链接的时候,如果请求网页失败或无网络的情况下,它会返回给我们这样一个页面,如下图所示: 上面这个页面就是系统自带的页面,你觉得是不是很丑?反正小编本人觉得非常丑,很难看,于是乎小编就在想能不能自定义一个页面,当数据请求失败时让系统来加载我们自定义好的页面?上网查了很多资料,都没有关于这个问题的解决方法(反正我是没有找到),经过小编的不断琢磨,今天终于实现了这个功能.以下就是本人自定义实现的数据加载失败时的页面: 这样看起来是不是觉得很高大尚.这和我们真正拿到数据

Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题

前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { switch(position){ case 0: fragments=new Fragmnet01(); break; case

Android实现自定义加载框的代码示例

App在与服务器进行网络交互的时候,需要有一个提示的加载框,如图: 此时我们可以自定义一个加载中的对话框,代码如下: public class LoadingDialog extends Dialog { private static final int CHANGE_TITLE_WHAT = 1; private static final int CHNAGE_TITLE_DELAYMILLIS = 300; private static final int MAX_SUFFIX_NUMBER

Android自定义View实现loading动画加载效果

项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

Android中自定义加载样式图片的具体实现

先让大家看看效果图吧,相信很多Android初学者都想知道这中效果是怎么实现的,来上图: 想实现上面这张图中的自定义加载样式,其实很简单,首先我们需要的布局组件有ProcessBar和TextView,下面是布局文件的代码(只是加载的页面的布局): 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.an

Android自定义view实现阻尼效果的加载动画

效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

Android 自定义view实现进度条加载效果实例代码

这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

Android自定义View仿华为圆形加载进度条

View仿华为圆形加载进度条效果图 实现思路 可以看出该View可分为三个部分来实现 最外围的圆,该部分需要区分进度圆和底部的刻度圆,进度部分的刻度需要和底色刻度区分开来 中间显示的文字进度,需要让文字在View中居中显示 旋转的小圆点,小圆点需要模拟小球下落运动时的加速度效果,开始下落的时候慢,到最底部时最快,上来时速度再逐渐减慢 具体实现 先具体细分讲解,博客最后面给出全部源码 (1)首先为View创建自定义的xml属性 在工程的values目录下新建attrs.xml文件 <resourc

Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码

在Android开发中我们常常用到圆形的头像,如果每次加载之后再进行圆形裁剪特别麻烦.所以在这里写一个自定义圆形ImageView,直接去加载网络图片,这样的话就特别的方便. 先上效果图 主要的方法 1.让自定义 CircleImageView 继承ImageView /** * 自定义圆形头像 * Created by Dylan on 2015/11/26 0026. */ public class CircleImageView extends ImageView { } 2.在构造方法中

Android 使用 Path 实现搜索动态加载动画效果

今天实现一个搜索动态加载数据的动画效果,还是先看效果吧,用文字描述干巴巴的,看图说话什么都明白了, 实现这个就是使用Path中的getSegment()不断的去改变它截取片段的start和stop,再结合动画,今天就分步骤实现它,看完以后你也会觉的不是很难,只是没想到这么实现而已,所以要多见识,所谓眼界决定你的高度,还是延续我写博客的习惯,一步步分析,第一步就是绘制如下图: 如果单纯的绘制这个图很简单很简单的,绘制一个圆,然后再绘制一根线就搞定,但是要考虑这里的效果,就不能这么干了,如果你看了上

android自定义view仿今日头条加载文字变色效果

本文实例为大家分享了android自定义view加载文字变色效果的具体代码,供大家参考,具体内容如下 不分析了,很简单,直接贴代码: package com.loading; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import

Android自定义WaveProgressView实现水波纹加载需求

先看效果图: 你可以定义成你项目的logo图片,可以设置水波颜色.波长.波宽.字体大小.颜色.进度条的最大值,当前进度值,还可以设置波纹震动的快慢.当设置一个进度不变的时候,打开时还有一个动画填满的效果(比如第二个流量显示,这里图片没有截出这个效果). 源码地址 1. 如何使用 1.1 在布局文件中 添加自定义控件: <cn.fanrunqi.waveprogressview.WaveProgressView android:id="@+id/waveProgressbar" a

Android实现仿慕课网下拉加载动画

具体实现方法就不多介绍了先附上源码,相信大家都容易看的懂: 这里为了让这个动画效果可被复用,于是就继承了ImageView 去实现某些方法 package com.example.loading_drawable; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.util.AttributeSet; import android.util.Log;