android 下拉刷新如何实现?

Mr.Black 2016-04-10 11:57:43
新手菜鸟一枚,求问各路大神,如何实现下拉刷新,网上查了几个方法都没成功,我的数据是从mysql里提取。
...全文
190 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
代号零零妖 2016-04-10
  • 打赏
  • 举报
回复

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class MainActivity extends Activity implements OnItemClickListener {

private List<String> numberList;
    private EditText etNumber;
    private NumberAdapter mAdapter;
    private PopupWindow pw;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

etNumber = (EditText) findViewById(R.id.et_number);
}

/**
     * 弹出选择号码的对话框
     * @param v
*/
public void showNumberList(View v) {
// 初始化ListView控件和里边的数据
ListView mListView = initListView();

// 弹出一个PopupWindow的窗体, 把ListView作为其内容部分显示.
pw = new PopupWindow(mListView, etNumber.getWidth() - 4, 300);

// 设置可以使用焦点
pw.setFocusable(true);

// 设置popupwindow点击外部可以被关闭
pw.setOutsideTouchable(true);
// 设置一个popupWindow的背景
pw.setBackgroundDrawable(new BitmapDrawable());

// 把popupwindow显示出来, 显示的位置是: 在输入框的下面, 和输入框是连着的.
pw.showAsDropDown(etNumber, 2, -5);
}

/**
     * 初始化一个Listview
     * @return
*/
private ListView initListView() {
        ListView mListView = new ListView(this);
mListView.setDividerHeight(0);
mListView.setBackgroundResource(R.drawable.listview_background);
// 去掉右侧垂直滑动条
mListView.setVerticalScrollBarEnabled(false);
mListView.setOnItemClickListener(this);

// 模拟数据
numberList = new ArrayList<String>();
        for (int i = 0; i < 30; i++) {
numberList.add("100000" + i);
}

// 设置适配器展示数据
mAdapter = new NumberAdapter();
mListView.setAdapter(mAdapter);
        return mListView;
}

class NumberAdapter extends BaseAdapter {

@Override
public int getCount() {
return numberList.size();
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
            NumberHolder mHolder = null;
            if(convertView == null) {
                convertView = View.inflate(MainActivity.this, R.layout.listview_item, null);
mHolder = new NumberHolder(); // 缓存类
mHolder.tvNumber = (TextView) convertView.findViewById(R.id.tv_listview_item_number);
mHolder.ibDelete = (ImageButton) convertView.findViewById(R.id.ib_listview_item_delete);
// 把Holder类设置给convertView对象.
convertView.setTag(mHolder);
} else {
                mHolder = (NumberHolder) convertView.getTag();
}

            mHolder.tvNumber.setText(numberList.get(position));
mHolder.ibDelete.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
                    System.out.println("删除: " + position);

numberList.remove(position);
mAdapter.notifyDataSetChanged();

// 如果全部的号码都被删除了, popupwindow应该被关闭掉.
if(numberList.size() == 0) {
pw.dismiss();
}
                }
            });
            return convertView;
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}
    }

class NumberHolder {
public TextView tvNumber;
        public ImageButton ibDelete;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
                            long id) {
        System.out.println("onItemClick: " + position);

String number = numberList.get(position);
etNumber.setText(number);
pw.dismiss();
}
}
代号零零妖 2016-04-10
  • 打赏
  • 举报
回复
刚才贴错代码了,你也可以使用第三方的pulltorefresh

package com.example.anzhe.myapplication;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by anzhe on 2016/4/7.
 */
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {
/**
     * 头布局的高度
     */
private int headerViewHeight;
/**
     * 手指按下的Y轴位置
     */
private int downY;

/**
     * 手指移动的Y轴位置
     */
private int moveY;
/**
     * Y轴移动的距离
     */
private int diffY;
    private View headerView;
/**
     * 最新的头布局高度
     */
private int paddingTop;
/**
     * 头布局状态: 下拉刷新
     */
private final int TYPE_DOWN = 0;
/**
     * 头布局状态: 释放刷新
     */
private final int TYPE_RELEASE = 1;
/**
     * 头布局状态: 正在刷新中..
     */
private final int TYPE_REFRESHING = 2;

/**
     * 当前头布局状态
     */
private int creentType = TYPE_DOWN;
/**
     * 下拉刷新动画
     */
private RotateAnimation donwnAnimation;
/**
     * 释放刷新动画
     */
private RotateAnimation upAnimation;
/**
     * 刷新中动画
     */
private RotateAnimation loadingAnimation;
/**
     * 头布局中的控件
     */
private ImageView pull;
    private TextView title;
    private ImageView loading;

/**
     * 使用者的回调接口
     */
private OnRefreshListener mOnRefreshListener;
/**
     * 是否加载更多中
     */
private boolean isLoadingMore = false;
    private View footerView;
    private int footerViewHeight;
    private ImageView loading_footer;
    private TextView title_footer;

    public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeaderView();
initFooterView();
initAnimation();
setOnScrollListener(this);
}

private void initFooterView() {
footerView = View.inflate(getContext(), R.layout.footer, null);
footerView.measure(0, 0);
footerViewHeight = footerView.getMeasuredHeight();
loading_footer = ((ImageView) footerView.findViewById(R.id.loading_footer));
title_footer = ((TextView) footerView.findViewById(R.id.title_footer));
// 隐藏底布局
footerView.setPadding(0, -footerViewHeight, 0, 0);
// 添加脚布局
this.addFooterView(footerView);
}


/**
     * 加载头布局
     */
private void initHeaderView() {
// 把头布局转换成View对象
headerView = View.inflate(getContext(), R.layout.header, null);
// 在当前界面添加一个头布局
this.addHeaderView(headerView);
// 获取头布局的高度, 必须使用measure获取头布局高, 在界面没显示出来之前.getHeight获取不到高度=0
headerView.measure(0, 0);// 让系统框架帮我们测量头布局的宽高
headerViewHeight = headerView.getMeasuredHeight();
// 隐藏头布局
headerView.setPadding(0, -headerViewHeight, 0, 0);

// 查找头布局中的控件
pull = ((ImageView) headerView.findViewById(R.id.pull));
title = ((TextView) headerView.findViewById(R.id.title));
loading = ((ImageView) headerView.findViewById(R.id.loading));
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
moveY = (int) ev.getY();
// 移动的间距
diffY = moveY - downY;
// 计算头布局最新的paddingTop = -头布局高度 + 间距.
paddingTop = diffY + -headerViewHeight;
// 获取ListView的第一挑item的索引
int firstVisiblePosition = getFirstVisiblePosition();
// 头布局当前移动的高度大于头布局高度.才可以滑动
if (paddingTop > -headerViewHeight && firstVisiblePosition == 0) {
if (paddingTop > 0 && creentType == TYPE_DOWN) {
// 松开刷新
creentType = TYPE_RELEASE;
refreshHeaderViewState();
} else if (paddingTop < 0 && creentType == TYPE_RELEASE) {
// 下拉刷新
creentType = TYPE_DOWN;
refreshHeaderViewState();
}
headerView.setPadding(0, paddingTop, 0, 0);
                    return true;
}
break;
            case MotionEvent.ACTION_UP:
if (creentType == TYPE_DOWN) {
// 当前状态是下拉状态, 松手应该隐藏头布局
headerView.setPadding(0, -headerViewHeight, 0, 0);
} else if (creentType == TYPE_RELEASE) {
// 当前状态是松开刷状态, 应该显示头布局
creentType = TYPE_REFRESHING;
headerView.setPadding(0, 0, 0, 0);
refreshHeaderViewState();
// 调用用户的监听事件
if (mOnRefreshListener != null) {
mOnRefreshListener.onPullDownRefresh();
}
                }

break;
}
return super.onTouchEvent(ev);
}

/**
     * 初始化动画
     */
private void initAnimation() {
donwnAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
donwnAnimation.setDuration(500);
donwnAnimation.setFillAfter(true);

upAnimation = new RotateAnimation(-180, -360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);

loadingAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
loadingAnimation.setDuration(500);
loadingAnimation.setRepeatCount(Animation.INFINITE);

}

private void refreshHeaderViewState() {
switch (creentType) {
case TYPE_DOWN:
// 下拉刷新
pull.startAnimation(upAnimation);
title.setText("下拉刷新");
                break;
            case TYPE_RELEASE:
// 释放立即刷新
title.setText("释放立即刷新");
pull.startAnimation(donwnAnimation);
                break;
            case TYPE_REFRESHING:
// 刷新中
title.setText("正在刷新...");
loading.setVisibility(View.VISIBLE);
pull.clearAnimation();
pull.setVisibility(View.INVISIBLE);
loading.startAnimation(loadingAnimation);
                break;
}
    }

/**
     * 当滚动状态改变时调用此方法
     * OnScrollListener.SCROLL_STATE_IDLE; 停滞状态
     * OnScrollListener.SCROLL_STATE_TOUCH_SCROLL; 手指触摸在屏幕上滑动.
     * OnScrollListener.SCROLL_STATE_FLING; 手指快速的滑动一下,有惯性的滑动。
     */
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// 当前的状态是停止, 并且屏幕上显示的最后一个条目的索引是ListView中总条目个数 -1;
if ((scrollState == OnScrollListener.SCROLL_STATE_IDLE    // 当前是停滞或者是快速滑动时
|| scrollState == OnScrollListener.SCROLL_STATE_FLING)
                && getLastVisiblePosition() == (getCount() - 1)
                && !isLoadingMore) {
            System.out.println("滑动到底部, 可以加载更多数据了.");

isLoadingMore = true;
footerView.setPadding(0, 0, 0, 0);
setSelection(getCount()); // 滑动到最底部

if (mOnRefreshListener != null) {
mOnRefreshListener.onLoadingMore();
}
        }
    }

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }


/**
     * 回调接口
     */
public interface OnRefreshListener {
/**
         * 当下拉刷新时回调此方法
         */
public void onPullDownRefresh();

/**
         * 当加载更多时调用此方法
         */
public void onLoadingMore();
}

/**
     * 提供给使用者设置刷新的监听事件
     *
     * @param listener
*/
public void setOnRefreshListener(OnRefreshListener listener) {
mOnRefreshListener = listener;
}

/**
     * 下拉刷新完成,隐藏头布局
     */
public void refreshFinish() {
if (isLoadingMore) { // 当前属于加载更多中
            // 隐藏脚布局
footerView.setPadding(0, -footerViewHeight, 0, 0);
isLoadingMore = false;

} else {
            Toast.makeText(getContext(), "刷新完成", Toast.LENGTH_LONG).show();
loading.setVisibility(View.INVISIBLE);
loading.clearAnimation();
creentType = TYPE_DOWN;
title.setText("下拉刷新");
headerView.setPadding(0, -headerViewHeight, 0, 0);
pull.setVisibility(View.VISIBLE);
}
    }
}
  • 打赏
  • 举报
回复
分批从数据库取数据,可以用sql语句的limit来实现,然后给ListView设置setOnScrollListener监听器,根据用户手指对ListView的操作来从数据从加载跟多的数据,监听代码大概如下: lv.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState){ case SCROLL_STATE_IDLE: break; case SCROLL_STATE_FLING: //可以在这里进行刷新,从数据库获取跟多的数据 break; case SCROLL_STATE_TOUCH_SCROLL: break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } });

80,359

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧