1、自定义ListView
import java.util.Date;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class RefreshAndLoadListView extends ListView {
private final static int RELEASE_To_REFRESH = 0;// 下拉过程的状态值
private final static int PULL_To_REFRESH = 1; // 从下拉返回到不刷新的状态值
private final static int REFRESHING = 2;// 正在刷新的状态值
private final static int DONE = 3;
private final static int LOADING = 4;
// 实际的padding的距离与界面上偏移距离的比例
private final static int RATIO = 3;
private LayoutInflater inflater;
// ListView头部下拉刷新的布局
private LinearLayout headerView;
private TextView lvHeaderTipsTv;
private TextView lvHeaderLastUpdatedTv;
private ImageView lvHeaderArrowIv;
private ProgressBar lvHeaderProgressBar;
// 定义头部下拉刷新的布局的高度
private int headerContentHeight;
private RotateAnimation animation;
private RotateAnimation reverseAnimation;
private int startY;// 摁下时的Y值;
private int state;// 当前的状态;
private boolean isBack;
// 用于保证startY的值在一个完整的touch事件中只被记录一次
private boolean isRecored;
private IReflashListener iReflashListener;//刷新数据的接口
public boolean isRefreshable;// 是否能够刷新
//底部加载布局
public LinearLayout lvFooterLayout;
private android.widget.LinearLayout.LayoutParams lvFooterProgressBarParams;
private android.widget.LinearLayout.LayoutParams lvFooterTipLoadingParams;
private android.widget.LinearLayout.LayoutParams lvFooterTipLoadedParams;
private ProgressBar lvFooterProgressBar;
private TextView lvTipLoading;
private TextView lvTipLoaded;
public boolean isFooterLoading;// 是否显示底部progressbar
public RefreshAndLoadListView(Context context) {
super(context);
init(context);
}
public RefreshAndLoadListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public RefreshAndLoadListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
//头部加载
inflater = LayoutInflater.from(context);
headerView = (LinearLayout) inflater.inflate(R.layout.header_layout, null);
lvHeaderTipsTv = (TextView) headerView
.findViewById(R.id.lvHeaderTipsTv);
lvHeaderLastUpdatedTv = (TextView) headerView
.findViewById(R.id.lvHeaderLastUpdatedTv);
lvHeaderArrowIv = (ImageView) headerView
.findViewById(R.id.lvHeaderArrowIv);
// 设置下拉刷新图标的最小高度和宽度
lvHeaderArrowIv.setMinimumWidth(70);
lvHeaderArrowIv.setMinimumHeight(50);
lvHeaderProgressBar = (ProgressBar) headerView
.findViewById(R.id.lvHeaderProgressBar);
measureView(headerView);
headerContentHeight = headerView.getMeasuredHeight();
// 设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏
headerView.setPadding(0, -1 * headerContentHeight, 0, 0);
// 重绘一下
headerView.invalidate();
// 将下拉刷新的布局加入ListView的顶部
addHeaderView(headerView, null, false);
// 设置滚动监听事件
//setOnScrollListener(this);
// 设置旋转动画事件
animation = new RotateAnimation(0, -180,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
reverseAnimation = new RotateAnimation(-180, 0,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
reverseAnimation.setInterpolator(new LinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
// 一开始的状态就是下拉刷新完的状态,所以为DONE
state = DONE;
// 是否正在刷新
isRefreshable = false;
//尾部加载
//news_study_list.setAdapter(adapter);
lvFooterLayout = new LinearLayout(context);
lvFooterLayout.setMinimumHeight(60);
lvFooterLayout.setGravity(Gravity.CENTER);
lvFooterLayout.setOrientation(LinearLayout.HORIZONTAL);
//尾部布局参数
lvFooterProgressBarParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lvFooterTipLoadingParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lvFooterTipLoadedParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
/**
* 向"加载项"布局中添加一个圆型进度条。
*/
lvFooterProgressBar = new ProgressBar(context);
lvFooterProgressBar.setPadding(0, 0, 15, 0);
/**
* 向"加载项"布局中添加提示信息。
*/
lvTipLoading = new TextView(context);
lvTipLoading.setText("加载中...");
lvTipLoaded = new TextView(context);
lvTipLoaded.setText("已加载全部");
lvFooterLayout.addView(lvFooterProgressBar, lvFooterProgressBarParams);
lvFooterLayout.addView(lvTipLoading, lvFooterTipLoadingParams);
lvFooterLayout.addView(lvTipLoaded,lvFooterTipLoadedParams);
/**
* 获取ListView组件,并将"加载项"布局添加到ListView组件的Footer中。
*/
addFooterView(lvFooterLayout);
isFooterLoading=true;//刚开始显示底部progerssbar
setFooterView(context,isFooterLoading);
}
/**
* 设置底部显示样式
* @param context
* @param isFooterLoading
*/
public void setFooterView(Context context,boolean isFooterLoading) {
this.isFooterLoading=isFooterLoading;
if(isFooterLoading){
lvFooterProgressBar.setVisibility(View.VISIBLE);
lvTipLoading.setVisibility(View.VISIBLE);
lvTipLoaded.setVisibility(View.GONE);
}else {
lvFooterProgressBar.setVisibility(View.GONE);
lvTipLoading.setVisibility(View.GONE);
lvTipLoaded.setVisibility(View.VISIBLE);
}
}
public void removeFooter(Context context){
removeFooterView(lvFooterLayout);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (isRefreshable) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isRecored) {
isRecored = true;
startY = (int) ev.getY();// 手指按下时记录当前位置
}
break;
case MotionEvent.ACTION_UP:
if (state != REFRESHING && state != LOADING) {
if (state == PULL_To_REFRESH) {
state = DONE;
changeHeaderViewByState();
}
if (state == RELEASE_To_REFRESH) {
state = REFRESHING;
changeHeaderViewByState();
onLvRefresh();
}
}
isRecored = false;
isBack = false;
break;
case MotionEvent.ACTION_MOVE:
int tempY = (int) ev.getY();
if (!isRecored) {
isRecored = true;
startY = tempY;
}
if (state != REFRESHING && isRecored && state != LOADING) {
// 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
// 可以松手去刷新了
if (state == RELEASE_To_REFRESH) {
setSelection(0);
// 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if (((tempY - startY) / RATIO < headerContentHeight)// 由松开刷新状态转变到下拉刷新状态
&& (tempY - startY) > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
// 一下子推到顶了
else if (tempY - startY <= 0) {// 由松开刷新状态转变到done状态
state = DONE;
changeHeaderViewByState();
}
}
// 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
if (state == PULL_To_REFRESH) {
setSelection(0);
// 下拉到可以进入RELEASE_TO_REFRESH的状态
if ((tempY - startY) / RATIO >= headerContentHeight) {// 由done或者下拉刷新状态转变到松开刷新
state = RELEASE_To_REFRESH;
isBack = true;
changeHeaderViewByState();
}
// 上推到顶了
else if (tempY - startY <= 0) {// 由DOne或者下拉刷新状态转变到done状态
state = DONE;
changeHeaderViewByState();
}
}
// done状态下
if (state == DONE) {
if (tempY - startY > 0) {
state = PULL_To_REFRESH;
changeHeaderViewByState();
}
}
// 更新headView的size
if (state == PULL_To_REFRESH) {
headerView.setPadding(0, -1 * headerContentHeight
+ (tempY - startY) / RATIO, 0, 0);
}
// 更新headView的paddingTop
if (state == RELEASE_To_REFRESH) {
headerView.setPadding(0, (tempY - startY) / RATIO
- headerContentHeight, 0, 0);
}
}
break;
default:
break;
}
}
return super.onTouchEvent(ev);
}
/** 当状态改变时候,调用该方法,以更新界面
*
*/
private void changeHeaderViewByState() {
switch (state) {
case RELEASE_To_REFRESH:
lvHeaderArrowIv.setVisibility(View.VISIBLE);
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderTipsTv.setVisibility(View.VISIBLE);
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();// 清除动画
lvHeaderArrowIv.startAnimation(animation);// 开始动画效果
lvHeaderTipsTv.setText("松开刷新");
break;
case PULL_To_REFRESH:
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderTipsTv.setVisibility(View.VISIBLE);
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setVisibility(View.VISIBLE);
// 是由RELEASE_To_REFRESH状态转变来的
if (isBack) {
isBack = false;
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.startAnimation(reverseAnimation);
lvHeaderTipsTv.setText("下拉刷新");
} else {
lvHeaderTipsTv.setText("下拉刷新");
}
break;
case REFRESHING:
headerView.setPadding(0, 0, 0, 0);
lvHeaderProgressBar.setVisibility(View.VISIBLE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setVisibility(View.GONE);
lvHeaderTipsTv.setText("正在刷新...");
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
break;
case DONE:
headerView.setPadding(0, -1 * headerContentHeight, 0, 0);
lvHeaderProgressBar.setVisibility(View.GONE);
lvHeaderArrowIv.clearAnimation();
lvHeaderArrowIv.setImageResource(R.drawable.pull_to_refresh_arrow);
lvHeaderTipsTv.setText("下拉刷新");
lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);
break;
}
}
/**此处是“估计”headView的width以及height
*
* @param child
*/
private void measureView(View child) {
ViewGroup.LayoutParams params = child.getLayoutParams();
if (params == null) {
params = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0,
params.width);
int lpHeight = params.height;
int childHeightSpec;
if (lpHeight > 0) {
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec, childHeightSpec);
}
public void setIRefreshListener(IReflashListener refreshListener) {
this.iReflashListener = refreshListener;
isRefreshable = true;
}
public interface IReflashListener {
public void onRefresh();
}
public void onRefreshComplete() {
state = DONE;
lvHeaderLastUpdatedTv.setText("最近更新:" + new Date().toLocaleString());
changeHeaderViewByState();
}
private void onLvRefresh() {
if (iReflashListener != null) {
iReflashListener.onRefresh();
}
}
public void setAdapter(BaseAdapter adapter) {
lvHeaderLastUpdatedTv.setText("最近更新:" + new Date().toLocaleString());
super.setAdapter(adapter);
}
}
2、实现下拉
public class NewsSystemListFragment extends BaseFragment implements IReflashListener,OnScrollListener
{
private NewsSystemAdapter adapter;
private ArrayList<SysNews> list;
private ArrayList<BaseSysNews> baseSysNewsList;
private SysNews sysNews;
private RefreshAndLoadListView news_sys_listView;
private Context context;
private boolean isHave = true;
public NewsSystemListFragment(ArrayList<SysNews> sysNewsList, Context context,
NewsSystemAdapter adapter)
{
this.adapter = adapter;
this.context = context;
this.list = sysNewsList;
}
public ArrayList<SysNews> getList()
{
return list;
}
public void setList(ArrayList<SysNews> list)
{
this.list = list;
}
public NewsSystemListFragment(boolean flag)
{
this.isHave = flag;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
public void onLoadingFailed(RequestParam param, FailResponse failRresponse) {
super.onLoadingFailed(param, failRresponse);
news_sys_listView.onRefreshComplete();
}
@Override
public void onLoadingComplete(RequestParam param) {
super.onLoadingComplete(param);
// 返回的是系统子新闻列表
baseSysNewsList = ((GetSysNewsTitleBean) param.getResponse()).Data;
news_sys_listView.onRefreshComplete();
if (baseSysNewsList == null) {
baseSysNewsList = new ArrayList<BaseSysNews>();
}
// 把系统子新闻列表放到系统新闻中
if (baseSysNewsList.size() == 0) {
sysNews = new SysNews();
} else {
sysNews = new SysNews(baseSysNewsList.get(0).SystemMessageId,
baseSysNewsList.get(0).ApplyDate,
baseSysNewsList.get(0).Title,
baseSysNewsList.get(0).MessageType,
baseSysNewsList.get(0).LogoImage);
}
int ListNum = baseSysNewsList.size();
for (int i = 1; i < ListNum; i++) {
sysNews.AppendNews(new BaseSysNews(baseSysNewsList.get(i)
.SystemMessageId, baseSysNewsList.get(i)
.ApplyDate, baseSysNewsList.get(i).Title,
baseSysNewsList.get(i).MessageType,
baseSysNewsList.get(i).LogoImage));
}
for (int i = ListNum; i < 6; i++) {
sysNews.AppendNews(new BaseSysNews());
}
// new Thread(){
//
// @Override
// public void run() {
// // TODO Auto-generated method stub
// super.run();
//把系统子新闻列表以及系统新闻放入数据库
SysNewsData.insertSysNew(context,baseSysNewsList,sysNews);
// 从数据库获取数据
((NewsActivity)context).setSysNewsData();
// }
//
// }.start();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (isHave)
{
View view =
inflater.inflate(R.layout.news_system_listfragment_listview, container, false);
news_sys_listView=(RefreshAndLoadListView) view.findViewById(R.id.news_sys_list);
news_sys_listView.setAdapter(adapter);
news_sys_listView.setSelection(adapter.getCount());
news_sys_listView.setIRefreshListener(this);
news_sys_listView.setOnScrollListener(this);
news_sys_listView.removeFooter(context);
return view;
}
else
{
return null;
}
}
@Override
public void onRefresh() {
runApi(new GetSysNewsTitleRequest("1"));
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0) {
news_sys_listView.isRefreshable = true;
} else {
news_sys_listView.isRefreshable = false;
}
}
}
3、实现下拉上滑
public class NewsStudyListFragment extends BaseFragment implements OnScrollListener,IReflashListener {
private RefreshAndLoadListView news_study_list;
private NewsStudyAdapter adapter;// 宝宝学习情况适配器
private ArrayList<StudyNews> list;
private ArrayList<StudyNews> newList;
private Context context;
private boolean isHave = true;
private int CurrentPage=1;
private int mLastItem = 0;
private int loadWay=0;//判断是上方加载还是下方加载
private final int UPLOAD=1;
private final int DOWNLOAD=2;
public NewsStudyListFragment(ArrayList<StudyNews> studyNews,Context context, NewsStudyAdapter adapter) {
this.adapter = adapter;
this.context = context;
this.list = studyNews;
}
public NewsStudyListFragment(boolean flag) {
this.isHave = flag;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (isHave) {
View view = inflater.inflate(R.layout.news_study_listfragment_listview, container,false);
news_study_list=(RefreshAndLoadListView) view.findViewById(R.id.news_study_list);
/**
* 组ListView组件设置Adapter,并设置滑动监听事件。
*/
news_study_list.setAdapter(adapter);
news_study_list.setOnScrollListener(this);
news_study_list.setIRefreshListener(this);
return view;
}else{
return null;
}
}
public ArrayList<StudyNews> getList() {
return list;
}
public void setList(ArrayList<StudyNews> list) {
this.list = list;
if(list.size()<10)
news_study_list.setFooterView(context, false);
}
@Override
public void onLoadingFailed(RequestParam param, FailResponse failRresponse) {
super.onLoadingFailed(param, failRresponse);
news_study_list.onRefreshComplete();
news_study_list.setFooterView(context, false);
}
@Override
public void onLoadingComplete(RequestParam param) {
super.onLoadingComplete(param);
if(loadWay==DOWNLOAD){
newList = ((GetStudyNewsBean) param.getResponse()).Data;
if (newList == null) {
newList = new ArrayList<StudyNews>();
}
if(newList.size()<10){
news_study_list.setFooterView(context, false);
}
list.addAll(newList);
if (adapter == null) {
adapter = new NewsStudyAdapter(context,
list);
} else {
adapter.onDataChange(list);
}
if(list.size()==0){
return;
}
}else if (loadWay==UPLOAD) {
list = ((GetStudyNewsBean) param.getResponse()).Data;
news_study_list.onRefreshComplete();
if (list == null) {
list = new ArrayList<StudyNews>();
}
if(list.size()<10){
news_study_list.setFooterView(context, false);
}else {
news_study_list.setFooterView(context, true);
}
if (adapter == null) {
adapter = new NewsStudyAdapter(context,list);
} else {
adapter.onDataChange(list);
}
if(list.size()==0){
return;
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
mLastItem = firstVisibleItem + visibleItemCount - 2;
if (firstVisibleItem == 0) {
news_study_list.isRefreshable = true;
} else {
news_study_list.isRefreshable = false;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
/**
* 当ListView滑动到最后一条记录时这时,我们会看到已经被添加到ListView的"加载项"布局, 这时应该加载剩余数据。
*/
if (mLastItem == adapter.getCount() && (scrollState == OnScrollListener.SCROLL_STATE_IDLE)
&& (news_study_list.isFooterLoading)&&(mLastItem>9)) {
loadWay=DOWNLOAD;
CurrentPage++;
runApi(new GetStudyNewsRequest(MyApplication.key, "1",CurrentPage+"","10"));
}
}
@Override
public void onRefresh() {
String key=MyApplication.key;
if (!"".equals(key) || null != key){
loadWay=UPLOAD;
CurrentPage=1;
runApi(new GetStudyNewsRequest(key, "1", CurrentPage+"", "10"));
news_study_list.setFooterView(context, true);
}
}
}
4、实现左拉删除
(1)自定义adapter
public class NewsBabyBuyAdapter extends BaseSwipeAdapter {
private Context context;
private ArrayList<BuyNews> list;
private AddCarOrBag addCar;
private ISwipeDel isd;
public interface BuyFromNews {
public void buy(String courseId, String price, String imageUrl,
String courseName);
}
public NewsBabyBuyAdapter(Context context, ArrayList<BuyNews> buyNews) {
this.context = context;
this.list = buyNews;
this.addCar = (AddCarOrBag) context;
this.isd = (ISwipeDel) context;
}
public void onDataChange(ArrayList<BuyNews> list) {
this.list = list;
this.notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getSwipeLayoutResourceId(int position) {
return R.id.buyNewsSwipe;
}
@Override
public View generateView(final int position, ViewGroup parent) {
View v = LayoutInflater.from(context).inflate(
R.layout.news_babybuy_item, parent, false);
final SwipeLayout swipeLayout = (SwipeLayout) v
.findViewById(getSwipeLayoutResourceId(position));
v.findViewById(R.id.ll_menu).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
isd.swipeToDel(position, swipeLayout);
}
});
return v;
}
@Override
public void fillValues(final int position, View convertView) {
TextView content = (TextView) convertView
.findViewById(R.id.news_baby_content);
TextView date = (TextView) convertView
.findViewById(R.id.news_baby_time);
Button bag = (Button) convertView
.findViewById(R.id.put_into_bag);
content.setText(list.get(position).CourseName);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String t = format.format(new Date());
date.setText(t);
if ((MyApplication.isVip) || ("0".equals(list.get(position).Price))) {
bag.setBackgroundResource(R.drawable.add_bag_default);
bag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// 会员进行加入书包操作
addCar.addToBag(list.get(position).CourseId);
}
});
} else {
bag.setBackgroundResource(R.drawable.news_baby_buy);
bag.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (NetWorkHelperUtil.isNetworkAvailable()) {
addCar.addToCar(list.get(position).CourseId, position);
} else {
Toast.makeText(context, "网络连接异常,请稍后再试",
Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
(2)实现接口
public interface ISwipeDel {
public void swipeToDel(int p, SwipeLayout swipeLayout);
}