English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
1.Agregar diseño de carga adicional
1_código de inicialización y ocultamiento
Se llama en el método constructor de RefreshListView
private void initFooterView(Context context) { View footerView = View.inflate(context, R.layout.refresh_listview_footer, null); //Código oculto footerView.measure(0, 0); int footerViewHeight = footerView.getMeasuredHeight(); footerView.setPadding(0, -footerViewHeight, 0, 0); this.addFooterView(footerView); }
2_layout_file_refresh_listview_footer.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" > <ProgressBar android:layout_margin="5dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminateDrawable="@drawable/custom_progressbar" /> <TextView android:layout_marginLeft="10dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cargando más..." android:textColor="#ff0000" android:textSize="25sp" /> </LinearLayout>
2cuando se arrastra hasta el fondo
/** * La página de pestaña de noticias correspondiente a la página del menú * En total12un * @author Administrador * */ public class TabMenuDetailPager extends MenuDetailBasePager implements OnPageChangeListener { /** * Centro de noticias-Los datos correspondientes a la etiqueta del menú de noticias */ private NewCenterTag newCenterTag; ..................... /** * URL para cargar más datos */ private String moreUrl; /** * ¿Está cargando más datos? */ protected boolean isLoadingMore = false; ................... @Override public View initView() { View view = View.inflate(mActivity, R.layout.tab_detail, null); //Inyectar View al marco XUtils ViewUtils.inject(this, view); .......................... //establecer escucha de refresco deslizante mListView.setOnRefreshListener(new OnRefreshListener() { @Override public void onPullDownRefresh() {}} isPullDownRefreshing = true; getDataFromNet(); } @Override public void onLoadingMore() { if(TextUtils.isEmpty(moreUrl)){ Toast.makeText(mActivity, "No hay más datos", 1).show(); mListView.onRefreshFinish(false); } else { //Hay más datos, debe cargar más datos. getMoreDataFromNet(); } } }); return view; } /** * Cargar más datos */ 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("Éxito al cargar más datos:");+responseInfo.result); mListView.onRefreshFinish(false); isLoadingMore = true; processData(responseInfo.result); } @Override public void onFailure(HttpException error, String msg) { mListView.onRefreshFinish(false); System.out.println("Falla al cargar más datos:");+ msg); } }); } /** * Procesar y analizar datos 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; //Establecer adaptador para ViewPager TabDetailAdapter adapter = new TabDetailAdapter(); mViewPager.setAdapter(adapter); // Limpiar todos los 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; //Establecer la descripción de la imagen predeterminada y los puntos de indicación mtv_title_description.setText(topnews.get(previousPointPosition).title); ll_point_group.getChildAt(previousPointPosition).setEnabled(true); //Establecer el escucha de cambio de página mViewPager.setOnPageChangeListener(this); //Establecer el adaptador y los datos correspondientes newsLists = bean.data.news; listViewAdapter = new ListViewAdapter(); mListView.setAdapter(listViewAdapter); // mListView.addHeaderView(v) ;//Agregar una vista de un extremo a la ListView } else { //Sacar las noticias de la lista, cargarlas en la colección anterior y actualizar los datos isLoadingMore = false; List<News>moreDataNews = bean.data.news; newsLists.addAll(moreDataNews); listViewAdapter.notifyDataSetChanged();//actualizar datos } } ................ /** * 用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; /** * Función: ListView con actualización deslizante personalizada */ public class RefreshListview extends ListView { /** * Actualización deslizante y presentación superior */ private LinearLayout headerView; /** * Control de actualización deslizante */ private View ll_pull_down_refresh; private ImageView iv_arrow; private ProgressBar pb_status; private TextView tv_status; private TextView tv_time; /** * Altura del control de actualización deslizante */ private int pullDownRefreshHeight; /** * Actualización deslizante */ public static final int PULL_DOWN_REFRESH = 0; /** * Actualizar cuando suelten */ public static final int RELEASE_REFRESH = 1; /** * En actualización */ public static final int REFRESHING = 2; /** * Estado actual */ private int currentStatus = PULL_DOWN_REFRESH; private Animation upAnimation; private Animation downAnimation; /** * Control de carga más */ private View footerView; /** * Altura del control de carga más */ private int footerViewHeight; /** * ¿Se han cargado más? */ private boolean isLoadMore = false; /** * Parte de la presentación superior */ private View topNewsView; /** * Coordenada en el eje Y del ListView */ 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); //agregar footer a ListView addFooterView(footerView); //escuchar el desplazamiento de ListView setOnScrollListener(new MyOnScrollListener()); } /** * agregar carrusel superior * @param topNewsView */ public void addTopNewsView(View topNewsView) { si(topNewsView != null){ this.topNewsView =topNewsView; headerView.addView(topNewsView); } } class MyOnScrollListener implements OnScrollListener{ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { //cuando está en estado de reposo o deslizamiento inercial if(scrollState ==OnScrollListener.SCROLL_STATE_IDLE||scrollState ==OnScrollListener.SCROLL_STATE_FLING){ //y es la última entrada visible if(getLastVisiblePosition()>=getCount())-1{ //1.mostrar el diseño de carga adicional footerView.setPadding(8,8,8,8); //2.cambio de estado isLoadMore = true; //3.interfaz de callback 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); //Control de actualización deslizante 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,-control de altura, 0,0);//completamente oculto //View.setPadding(0, 0, 0, 0);//completamente visible 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){ //Cargar más 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) { //Estado de actualización deslizante currentStatus = PULL_DOWN_REFRESH; //actualizar el estado refreshViewState(); else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) { //Estado de soltar para actualizar currentStatus = RELEASE_REFRESH; //actualizar el estado refreshViewState(); } ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0); //View.setPadding(0,paddingTop,0,0);//mostrar dinámicamente el control de actualización向下 } break; case MotionEvent.ACTION_UP: startY = -1; si (currentStatus == PULL_DOWN_REFRESH) { // View.setPadding(0,-control de altura, 0,0);//completamente oculto ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0); } de lo contrario si (currentStatus == RELEASE_REFRESH) { //establecer el estado como está en actualización currentStatus = REFRESHING; refreshViewState(); // View.setPadding(0,0,0,0);//completamente visible ll_pull_down_refresh.setPadding(0, 0, 0, 0); //interfaz de devolución de llamada si (mOnRefreshListener != null) { mOnRefreshListener.onPullDownRefresh(); } } break; } return super.onTouchEvent(ev); } /** * juzgar si el carrusel superior se muestra completamente * cuando la coordenada Y en la pantalla del ListView es menor o igual a la coordenada Y del carrusel superior, el carrusel superior se muestra completamente * @return */ private boolean isDisplayTopNews() { si(topNewsView != null){ //1.obtener las coordenadas en la pantalla del ListView int[] location = new int[2; si(listViewOnScreenY === -1{ getLocationOnScreen(location); listViewOnScreenY = location[1; } //2.obtener las coordenadas en la pantalla del carrusel superior topNewsView.getLocationOnScreen(location); int topNewsViewOnScreenY = location[1; // si(listViewOnScreenY <= topNewsViewOnScreenY){ // return true; // } else { // return false; // } return listViewOnScreenY <= topNewsViewOnScreenY; } else { return true; } } private void refreshViewState() { switch (currentStatus) { case PULL_DOWN_REFRESH://Estado de actualización deslizante iv_arrow.startAnimation(downAnimation); tv_status.setText("Actualización deslizante..."); break; case RELEASE_REFRESH://Estado de soltar para actualizar iv_arrow.startAnimation(upAnimation); tv_status.setText("Soltar para actualizar..."); break; case REFRESHING://Estado de actualización en curso tv_status.setText("Actualizando..."); pb_status.setVisibility(VISIBLE); iv_arrow.clearAnimation(); iv_arrow.setVisibility(GONE); break; } } /** * Llamar a este método cuando se conecte a Internet con éxito o fracase * Restaurar el estado de actualización del usuario * * @param sucess */ public void onRefreshFinish(boolean sucess) { if(isLoadMore){ //Cargar más isLoadMore = false; //Ocultar el diseño de carga adicional footerView.setPadding(0,-footerViewHeight,0,0); } else { //Actualización deslizante tv_status.setText("Actualización deslizante..."); currentStatus = PULL_DOWN_REFRESH; iv_arrow.clearAnimation(); pb_status.setVisibility(GONE); iv_arrow.setVisibility(VISIBLE); //Ocultar el control de actualización deslizante ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0); if (sucess) { //Establecer la hora de actualización más reciente tv_time.setText("Última actualización: "); + getSystemTime()); } } } /** * Obtener la hora actual del sistema Android * * @return */ private String getSystemTime() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return format.format(new Date()); } /** * Escuchar el refresco del controlador */ public interface OnRefreshListener { /** * Llame a este método cuando se actualice hacia abajo */ public void onPullDownRefresh(); /** Llame a este método cuando se cargue más */ public void onLoadMore(); } private OnRefreshListener mOnRefreshListener; /** * Establecer el escucha de actualización, establecido por el exterior */ public void setOnRefreshListener(OnRefreshListener l) { this.mOnRefreshListener = l; } }
Lo mencionado anteriormente es lo que el editor les ha presentado sobre el deslizamiento de descarga de noticias similar a Silicon Valley en Android/Arrastrar hacia arriba para cargar más, espero que sea útil para todos. Si tienen alguna pregunta, déjenme un mensaje y el editor responderá a tiempo. También agradezco muchísimo el apoyo de todos a la página web de呐喊教程!
Declaración: el contenido de este artículo se obtiene de la red, es propiedad del autor original, el contenido se contribuye y carga de manera autónoma por los usuarios de Internet, este sitio no posee los derechos de propiedad, no se ha editado de manera humana y no asume responsabilidades legales relacionadas. Si encuentra contenido sospechoso de infracción de derechos de autor, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, por favor reemplace # con @) para denunciar y proporcionar evidencia relevante. Una vez verificada, este sitio eliminará inmediatamente el contenido sospechoso de infracción.