English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

تقليد Silicon Valley News للتحديث السريع السحابي/السحب لأكثر

1.添加加载更多布局

1_初始化和隐藏代码

在RefreshListView构造方法中调用

private void initFooterView(Context context) {
View footerView = View.inflate(context, R.layout.refresh_listview_footer, null);
//隐藏代码
footerView.measure(0, 0);
int footerViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -footerViewHeight, 0, 0);
this.addFooterView(footerView);
}

2_布局文件refresh_listview_footer.xml





2. عند سحب إلى أسفل إلى الحد الأدنى

/**
* صفحة الأخبار الم对应ة لصفحة القائمة
* يوجد 12 منها
* @author Administrator
*
*/
public class TabMenuDetailPager extends MenuDetailBasePager implements OnPageChangeListener {
/**
* بيانات العلامة الم对应ة لقائمة الأخبار في مركز الأخبار
*/
private NewCenterTag newCenterTag;
.......................
/**
* URL تحميل المزيد من البيانات
*/
private String moreUrl;
/**
* هل يتم تحميل المزيد من البيانات؟
*/
protected boolean isLoadingMore = false;
...................
@Override
public View initView() {
View view = View.inflate(mActivity, R.layout.tab_detail, null);
// إدراج View في إطار XUtils
ViewUtils.inject(this, view); 
.......................... 
// إعداد الاستماع إلى تحديث السحب إلى الأسفل
mListView.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onPullDownRefresh() {
isPullDownRefreshing = true;
getDataFromNet();
}
@Override
public void onLoadingMore() {
if(TextUtils.isEmpty(moreUrl)){
Toast.makeText(mActivity, "لا يوجد المزيد من البيانات", 1).show();
mListView.onRefreshFinish(false);
} else {
// هناك المزيد من البيانات، يجب تحميل المزيد من البيانات
getMoreDataFromNet();
}
}
});
return view;
}
/**
* تحميل المزيد من البيانات
*/
protected void getMoreDataFromNet() {
HttpUtils httpUtils = new HttpUtils();
httpUtils.send(HttpMethod.GET, moreUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
System.out.println("加载更多数据成功:"+responseInfo.result);
mListView.onRefreshFinish(false);
isLoadingMore = true;
processData(responseInfo.result);
}
@Override
public void onFailure(HttpException error, String msg) {
mListView.onRefreshFinish(false);
System.out.println("加载更多数据失败:"+ msg);
}
}); 
}
/**
* 处理和解析json数据
* @param json
*/
protected void processData(String json) {
TabDetailBean bean = parserJson(json);
if(!isLoadingMore){
System.out.println(bean.data.news.get(0).title);
topnews = bean.data.topnews;
//给ViewPager设置适配器
TabDetailAdapter adapter = new TabDetailAdapter();
mViewPager.setAdapter(adapter);
// 把所有的View清除
ll_point_group.removeAllViews();
for(int i=0;i<topnews.size();i++){
View point = new View(mActivity);
LayoutParams params = new LayoutParams(5, 5) ;
point.setBackgroundResource(R.drawable.tab_detail_point_bg);
if(i!=0){
params.leftMargin = 10;
}
point.setEnabled(false);
point.setLayoutParams(params);
ll_point_group.addView(point);
}
previousPointPosition = 0;
//ضبط التوصيف الصور الافتراضي وأشرطة الإرشاد
mtv_title_description.setText(topnews.get(previousPointPosition).title);
ll_point_group.getChildAt(previousPointPosition).setEnabled(true);
//ضبط مستمع تغيير الصفحة
mViewPager.setOnPageChangeListener(this);
//ضبط الربط والبيانات الم对应ه
newsLists = bean.data.news;
listViewAdapter = new ListViewAdapter();
mListView.setAdapter(listViewAdapter);
// mListView.addHeaderView(v) ;//إضافة عرض إلى ListView بشكل رأس 
} else {
//استخراج قائمة الأخبار وتحميلها إلى المجموعة السابقة، ثم تحديث البيانات
isLoadingMore = false;
List<News>moreDataNews = bean.data.news;
newsLists.addAll(moreDataNews);
listViewAdapter.notifyDataSetChanged();//تحديث البيانات
}
}
................
/**
* باستخدام مشروع Gson المفتوح المصدر لتحليل json
* @param json
*/
private TabDetailBean parserJson(String json) {
Gson gson = new Gson();
TabDetailBean bean = gson.fromJson(json, TabDetailBean.class);
moreUrl = bean.data.more;
if(TextUtils.isEmpty(moreUrl)){
moreUrl = null;
} else {
moreUrl = ConstantUtils.server_url+moreUrl;
}
return bean;
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
...............
}

3. الكود الكامل

package com.atguigu.refreshlistview;
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.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* وظيفة: قائمة ListView مخصصة للسحب نحو الأسفل
*/
public class RefreshListview extends ListView {
/**
* السحب نحو الأسفل والعرض التلقائي في القمة
*/
private LinearLayout headerView;
/**
* عنصر السحب نحو الأسفل
*/
private View ll_pull_down_refresh;
private ImageView iv_arrow;
private ProgressBar pb_status;
private TextView tv_status;
private TextView tv_time;
/**
* اعادة تحديث عنصر السحب نحو الأسفل
*/
private int pullDownRefreshHeight;
/**
* تحديث سحب لأسفل
*/
public static final int PULL_DOWN_REFRESH = 0;
/**
* تحديث عند إطلاق اليد
*/
public static final int RELEASE_REFRESH = 1;
/**
* يتم التحديث
*/
public static final int REFRESHING = 2;
/**
* الحالة الحالية
*/
private int currentStatus = PULL_DOWN_REFRESH;
private Animation upAnimation;
private Animation downAnimation;
/**
* عنصر تحميل المزيد
*/
private View footerView;
/**
* طول عنصر تحميل المزيد
*/
private int footerViewHeight;
/**
* هل تم تحميل المزيد؟
*/
private boolean isLoadMore = false;
/**
* جزء العرض التلقائي في الاعلى
*/
private View topNewsView;
/**
* ListView في المحور Y
*/
private int listViewOnScreenY = -1;
public RefreshListview(Context context) {
this(context, null);
}
public RefreshListview(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshListview(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView(context);
initAnimation();
initFooterView(context);
}
private void initFooterView(Context context) {
footerView = View.inflate(context, R.layout.refresh_footer, null);
footerView.measure(0, 0);
footerViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -footerViewHeight, 0, 0);
//ListView添加footer
addFooterView(footerView);
//监听ListView的滚动
setOnScrollListener(new MyOnScrollListener());
}
/**
* 添加顶部轮播图
* @param topNewsView
*/
public void addTopNewsView(View topNewsView) {
if(topNewsView != null){
this.topNewsView =topNewsView;
headerView.addView(topNewsView);
}
}
class MyOnScrollListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//当静止或者惯性滚动的时候
if(scrollState ==OnScrollListener.SCROLL_STATE_IDLE||scrollState ==OnScrollListener.SCROLL_STATE_FLING){
//并且是最后一条可见
if(getLastVisiblePosition()>=getCount()-1){
//1.显示加载更多布局
footerView.setPadding(8,8,8,8);
//2.状态改变
isLoadMore = true;
//3.回调接口
if(mOnRefreshListener != null){
mOnRefreshListener.onLoadMore();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
}
private void initAnimation() {
upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);
downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(500);
downAnimation.setFillAfter(true);
}
private void initHeaderView(Context context) {
headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null);
//下拉刷新控件
ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
tv_status = (TextView) headerView.findViewById(R.id.tv_status);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
//测量
ll_pull_down_refresh.measure(0, 0);
pullDownRefreshHeight = ll_pull_down_refresh.getMeasuredHeight();
//الإخفاء الافتراضي لشريط التحديث السريع
// View.setPadding(0,-طول العنصر،0,0);//يتم إخفاء بشكل كامل
//View.setPadding(0, 0,0,0);// العرض الكامل
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
//إضافة رأس ListView
addHeaderView(headerView);
}
private float startY = -1;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//1.تسجيل مركز البداية
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (startY == -1) {
startY = ev.getY();
}
//تحديد ما إذا كان عرض العرض التلقائي في الوجهة العليا كاملاً أم لا، فقط عندما يكون كاملاً يمكن سحب التحديث
boolean isDisplayTopNews = isDisplayTopNews();
if(!isDisplayTopNews){
// تحميل المزيد
break;
}
//إذا كان يتم التحديث حاليًا، لا يسمح بتحديث إضافي
if (currentStatus == REFRESHING) {
break;
}
//2.وصول إلى مركز جديد
float endY = ev.getY();
//3.تسجيل مسافة التمرير
float distanceY = endY - startY;
if (distanceY > 0) {//سحب
//int paddingTop = -ارتفاع الشريط + distanceY;
int paddingTop = (int) (-pullDownRefreshHeight + distanceY);
if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) {
//حالة سحب لتحديث
currentStatus = PULL_DOWN_REFRESH;
//تحديث الحالة
refreshViewState();
} else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) {
//حالة تحرير اليد لتحديث
currentStatus = RELEASE_REFRESH;
//تحديث الحالة
refreshViewState();
}
ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0);
//View.setPadding(0,paddingTop,0,0);//العرض التدريجي لشريط التحديث السريع
}
break;
case MotionEvent.ACTION_UP:
startY = -1;
if (currentStatus == PULL_DOWN_REFRESH) {
// View.setPadding(0,-طول العنصر،0,0);//يتم إخفاء بشكل كامل
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
} else if (currentStatus == RELEASE_REFRESH) {
//إعداد الحالة كأن تكون في عملية تحديث
currentStatus = REFRESHING;
refreshViewState();
// View.setPadding(0,0،0,0);//يظهر بشكل كامل
ll_pull_down_refresh.setPadding(0, 0, 0, 0);
// واجهة التتبع
if (mOnRefreshListener != null) {
mOnRefreshListener.onPullDownRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}
/**
* تحديد ما إذا كان الشريط العلوية يظهر بشكل كامل
* عندما يكون موقع Y المحوري للListView في الشاشة أقل أو يساوي موقع Y المحوري للشريط العلوية في الشاشة، يتم عرض الشريط العلوية بشكل كامل
* @return
*/
private boolean isDisplayTopNews() {
if(topNewsView != null){
//1.得到ListView在屏幕上的坐标
int[] location = new int[2];
if(listViewOnScreenY == -1){
getLocationOnScreen(location);
listViewOnScreenY = location[1];
}
//2.得到顶部轮播图在屏幕上的坐标
topNewsView.getLocationOnScreen(location);
int topNewsViewOnScreenY = location[1];
// if(listViewOnScreenY <= topNewsViewOnScreenY){
// return true;
// }else{
// return false;
// }
return listViewOnScreenY <= topNewsViewOnScreenY;
} else {
return true;
}
}
private void refreshViewState() {
switch (currentStatus) {
case PULL_DOWN_REFRESH:// حالة التحديث بسحب للأسفل
iv_arrow.startAnimation(downAnimation);
tv_status.setText("تحديث سحب...");
break;
case RELEASE_REFRESH:// حالة السحب عند الإفراج
iv_arrow.startAnimation(upAnimation);
tv_status.setText("السحب لتحديث...");
break;
case REFRESHING:// حالة التحديث الجارية
tv_status.setText("جاري التحديث...");
pb_status.setVisibility(VISIBLE);
iv_arrow.clearAnimation();
iv_arrow.setVisibility(GONE);
break;
}
}
/**
* يتم استدعاء هذه الطريقة عند الاتصال الناجح والفشل بالإنترنت
* استعادة حالة التصفية للمستخدم
*
* @param sucess
*/
public void onRefreshFinish(boolean sucess) {
if(isLoadMore){
// تحميل المزيد
isLoadMore = false;
// إخفاء نموذج تحميل المزيد
footerView.setPadding(0, -footerViewHeight, 0, 0);
} else {
// تحديث سحب
tv_status.setText("تحديث سحب...");
currentStatus = PULL_DOWN_REFRESH;
iv_arrow.clearAnimation();
pb_status.setVisibility(GONE);
iv_arrow.setVisibility(VISIBLE);
// إخفاء عنصر تحديث السحب
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
if (sucess) {
// إعداد وقت التحديث الأحدث
tv_time.setText("وقت التحديث الأخير: " + getSystemTime());
}
}
}
/**
* الحصول على وقت النظام الحالي لـ Android
*
* @return
*/
private String getSystemTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
/**
* الاستماع إلى تحديث العنصر
*/
public interface OnRefreshListener {
/**
* عند سحب التحديث، يتم استدعاء هذه الطريقة
*/
public void onPullDownRefresh();
/**
عند تحميل المزيد، يتم استدعاء هذه الطريقة
*/
public void onLoadMore();
}
private OnRefreshListener mOnRefreshListener;
/**
* إعداد الاستماع إلى التحديث، يتم إعداده من الخارج
*/
public void setOnRefreshListener(OnRefreshListener l) {
this.mOnRefreshListener = l;
}
}

ما ذكرناه أعلاه هو ما قدمه المحرر لكم من Android Simulated Silicon Valley News Pull Down Refresh / Pull Up Load More، نأمل أن يكون مفيدًا لكم، إذا كان لديكم أي أسئلة، يرجى ترك تعليق، وسأقوم بالرد على أسئلتكم في أقرب وقت. شكرًا جزيلاً أيضًا لتأييدكم لموقع呐喊 لتعليم البرمجة!

بيان: محتوى هذا المقال تم جمعه من الإنترنت، ويتمتع المالك الأصلي بحقوق الطبع والنشر، ويتم جمع المحتوى من قبل المستخدمين عبر الإنترنت ويتم تحميله بشكل مستقل، ويملك هذا الموقع حقوق الملكية، ولا يتم تعديل المحتوى بشكل يدوي، ولا يتحمل هذا الموقع أي مسؤولية قانونية. إذا كنت قد وجدت محتوى يشتبه في انتهاك حقوق النسخ، فلا تتردد في إرسال بريد إلكتروني إلى: notice#oldtoolbag.com (عند إرسال البريد الإلكتروني، يرجى استبدال # ب @) لإبلاغنا، وقدم الدليل المتعلق، وسيتم حذف المحتوى المزعوم الذي يشتبه في انتهاك حقوق النسخ فورًا.

أنت قد تحب