iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android UI自定义ListView实现下拉刷新和加载更多效果
  • 901
分享到

Android UI自定义ListView实现下拉刷新和加载更多效果

listviewAndroid 2022-06-06 05:06:54 901人浏览 独家记忆
摘要

关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆。不过我就没发现比较实用的,要不就是实现起来太复杂,要不就是不健全的。因为小巫近期要开发新浪微博客户端,需要

关于实现ListView下拉刷新和加载更多的实现,我想网上一搜就一堆。不过我就没发现比较实用的,要不就是实现起来太复杂,要不就是不健全的。因为小巫近期要开发新浪微博客户端,需要实现ListView的下拉刷新,所以就想把这个UI整合到项目当中去,这里只是一个demo,可以根据项目的需要进行修改。

就不要太在乎界面了哈:



知道你们想要源码了,去下吧:Http://download.csdn.net/detail/wwj_748/6373183

自定义ListView:


package com.markupartist.Android.widget; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import com.markupartist.android.example.pulltorefresh.R; 
import android.content.Context; 
import android.util.AttributeSet; 
import android.util.Log; 
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.AbsListView; 
import android.widget.AbsListView.OnScrollListener; 
import android.widget.ImageView; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 
 
public class PullToRefreshListView extends ListView implements OnScrollListener { 
  private static final int TAP_TO_REFRESH = 1;      //(未刷新) 
  private static final int PULL_TO_REFRESH = 2;      // 下拉刷新 
  private static final int RELEASE_TO_REFRESH = 3;    // 释放刷新 
  private static final int REFRESHING = 4;        // 正在刷新 
  private static final int TAP_TO_LOADMORE = 5;      // 未加载更多 
  private static final int LOADING = 6;          // 正在加载 
  private static final String TAG = "PullToRefreshListView"; 
  private OnRefreshListener mOnRefreshListener;      // 刷新监听器 
   
  private OnScrollListener mOnScrollListener;       // 列表滚动监听器 
  private LayoutInflater mInflater;            // 用于加载布局文件 
  private RelativeLayout mRefreshHeaderView;       // 刷新视图(也就是头部那部分)   
  private TextView mRefreshViewText;           // 刷新提示文本     
  private ImageView mRefreshViewImage;          // 刷新向上向下的那个图片 
  private ProgressBar mRefreshViewProgress;        // 这里是圆形进度条 
  private TextView mRefreshViewLastUpdated;        // 最近更新的文本 
  private RelativeLayout mLoadMoreFooterView;       // 加载更多 
  private TextView mLoadMoreText;             // 提示文本 
  private ProgressBar mLoadMoreProgress;         // 加载更多进度条 
  private int mCurrentScrollState;            // 当前滚动位置       
  private int mRefreshState;               // 刷新状态  
  private int mLoadState;                 // 加载状态 
  private RotateAnimation mFlipAnimation;         // 下拉动画 
  private RotateAnimation mReverseFlipAnimation;     // 恢复动画 
  private int mRefreshViewHeight;             // 刷新视图高度           
  private int mRefreshOriginalTopPadding;         // 原始上部间隙 
  private int mLastMotionY;                // 记录点击位置 
  public PullToRefreshListView(Context context) { 
    super(context); 
    init(context); 
  } 
  public PullToRefreshListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    init(context); 
  } 
  public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    init(context); 
  } 
  private void init(Context context) { 
    // Load all of the animations we need in code rather than through XML 
     
    // 参数:1.旋转开始的角度 2.旋转结束的角度 3. X轴伸缩模式 4.X坐标的伸缩值 5.Y轴的伸缩模式 6.Y坐标的伸缩值 
    mFlipAnimation = new RotateAnimation(0, -180, 
        RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
        RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
    mFlipAnimation.setInterpolator(new LinearInterpolator()); 
    mFlipAnimation.setDuration(250);        // 设置持续时间 
    mFlipAnimation.setFillAfter(true);       // 动画执行完是否停留在执行完的状态 
    mReverseFlipAnimation = new RotateAnimation(-180, 0, 
        RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
        RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
    mReverseFlipAnimation.setInterpolator(new LinearInterpolator()); 
    mReverseFlipAnimation.setDuration(250); 
    mReverseFlipAnimation.setFillAfter(true); 
    // 获取LayoutInflater实例对象 
    mInflater = (LayoutInflater) context.getSystemService( 
        Context.LAYOUT_INFLATER_SERVICE); 
    // 加载下拉刷新的头部视图 
    mRefreshHeaderView = (RelativeLayout) mInflater.inflate( 
        R.layout.pull_to_refresh_header, this, false); 
    mRefreshViewText = 
      (TextView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_text); 
    mRefreshViewImage = 
      (ImageView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_image); 
    mRefreshViewProgress = 
      (ProgressBar) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_progress); 
    mRefreshViewLastUpdated = 
      (TextView) mRefreshHeaderView.findViewById(R.id.pull_to_refresh_updated_at); 
    mLoadMoreFooterView = (RelativeLayout) mInflater.inflate( 
        R.layout.loadmore_footer, this, false); 
    mLoadMoreText = (TextView) mLoadMoreFooterView.findViewById(R.id.loadmore_text); 
    mLoadMoreProgress = (ProgressBar) mLoadMoreFooterView.findViewById(R.id.loadmore_progress); 
    mRefreshViewImage.setMinimumHeight(50);   // 设置图片最小高度 
    mRefreshHeaderView.setOnClickListener(new OnClickRefreshListener()); 
    mRefreshOriginalTopPadding = mRefreshHeaderView.getPaddingTop(); 
    mLoadMoreFooterView.setOnClickListener(new OnClickLoadMoreListener()); 
    mRefreshState = TAP_TO_REFRESH;       // 初始刷新状态 
    mLoadState = TAP_TO_LOADMORE; 
    addHeaderView(mRefreshHeaderView);     // 增加头部视图 
    addFooterView(mLoadMoreFooterView);     // 增加尾部视图 
    super.setOnScrollListener(this);     
    measureView(mRefreshHeaderView);        // 测量视图 
    mRefreshViewHeight = mRefreshHeaderView.getMeasuredHeight();  // 得到视图的高度 
  } 
  @Override 
  protected void onAttachedToWindow() { 
    setSelection(1);    // 设置当前选中的项 
  } 
  @Override 
  public void setAdapter(ListAdapter adapter) { 
    super.setAdapter(adapter); 
    setSelection(1); 
  } 
   
  @Override 
  public void setOnScrollListener(AbsListView.OnScrollListener l) { 
    mOnScrollListener = l; 
  } 
   
  public void setOnRefreshListener(OnRefreshListener onRefreshListener) { 
    mOnRefreshListener = onRefreshListener; 
  } 
   
  public void setLastUpdated(CharSequence lastUpdated) { 
    if (lastUpdated != null) { 
      mRefreshViewLastUpdated.setVisibility(View.VISIBLE); 
      mRefreshViewLastUpdated.setText("更新于: " + lastUpdated); 
    } else { 
      mRefreshViewLastUpdated.setVisibility(View.GoNE); 
    } 
  } 
  @Override 
  public boolean onTouchEvent(MotionEvent event) { 
    final int y = (int) event.getY();  // 获取点击位置的Y坐标 
    switch (event.getAction()) { 
      case MotionEvent.ACTION_UP:   // 手指抬起 
        if (!isVerticalScrollBarEnabled()) { 
          setVerticalScrollBarEnabled(true); 
        } 
        if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) { 
          if ((mRefreshHeaderView.getBottom() > mRefreshViewHeight 
              || mRefreshHeaderView.getTop() >= 0) 
              && mRefreshState == RELEASE_TO_REFRESH) { 
            // Initiate the refresh 
            mRefreshState = REFRESHING;   // 刷新状态 
            prepareForRefresh(); 
            onRefresh(); 
          } else if (mRefreshHeaderView.getBottom() < mRefreshViewHeight 
              || mRefreshHeaderView.getTop() < 0) { 
            // Abort refresh and scroll down below the refresh view 
            resetHeader(); 
            setSelection(1); 
          } 
        } 
        break; 
      case MotionEvent.ACTION_DOWN: 
        mLastMotionY = y; 
        break; 
      case MotionEvent.ACTION_MOVE: 
        applyHeaderPadding(event); 
        break; 
    } 
    return super.onTouchEvent(event); 
  } 
  private void applyHeaderPadding(MotionEvent ev) { 
    final int historySize = ev.getHistorySize(); 
    // Workaround for getPointerCount() which is unavailable in 1.5 
    // (it's always 1 in 1.5) 
    int pointerCount = 1; 
    try { 
      Method method = MotionEvent.class.getMethod("getPointerCount"); 
      pointerCount = (Integer)method.invoke(ev); 
    } catch (NoSuchMethodException e) { 
      pointerCount = 1; 
    } catch (IllegalArgumentException e) { 
      throw e; 
    } catch (IllegalAccessException e) { 
      System.err.println("unexpected " + e); 
    } catch (InvocationTargetException e) { 
      System.err.println("unexpected " + e); 
    } 
    for (int h = 0; h < historySize; h++) { 
      for (int p = 0; p < pointerCount; p++) { 
        if (mRefreshState == RELEASE_TO_REFRESH) { 
          if (isVerticalFadingEdgeEnabled()) { 
            setVerticalScrollBarEnabled(false); 
          } 
          int historicalY = 0; 
          try { 
            // For Android > 2.0 
            Method method = MotionEvent.class.getMethod( 
                "getHistoricalY", Integer.TYPE, Integer.TYPE); 
            historicalY = ((Float) method.invoke(ev, p, h)).intValue(); 
          } catch (NoSuchMethodException e) { 
            // For Android < 2.0 
            historicalY = (int) (ev.getHistoricalY(h)); 
          } catch (IllegalArgumentException e) { 
            throw e; 
          } catch (IllegalAccessException e) { 
            System.err.println("unexpected " + e); 
          } catch (InvocationTargetException e) { 
            System.err.println("unexpected " + e); 
          } 
          // Calculate the padding to apply, we divide by 1.7 to 
          // simulate a more resistant effect during pull. 
          int topPadding = (int) (((historicalY - mLastMotionY) 
              - mRefreshViewHeight) / 1.7); 
          // 设置上、下、左、右四个位置的间隙间隙 
          mRefreshHeaderView.setPadding( 
              mRefreshHeaderView.getPaddingLeft(), 
              topPadding, 
              mRefreshHeaderView.getPaddingRight(), 
              mRefreshHeaderView.getPaddingBottom()); 
        } 
      } 
    } 
  } 
   
  private void resetHeaderPadding() { 
    mRefreshHeaderView.setPadding( 
        mRefreshHeaderView.getPaddingLeft(), 
        mRefreshOriginalTopPadding, 
        mRefreshHeaderView.getPaddingRight(), 
        mRefreshHeaderView.getPaddingBottom()); 
  } 
   
  private void resetHeader() { 
    if (mRefreshState != TAP_TO_REFRESH) { 
      mRefreshState = TAP_TO_REFRESH; 
      resetHeaderPadding(); 
      // Set refresh view text to the pull label 
      mRefreshViewText.setText(R.string.pull_to_refresh_tap_label); 
      // Replace refresh drawable with arrow drawable 
      mRefreshViewImage.setImageResource(R.drawable.ic_pulltorefresh_arrow); 
      // Clear the full rotation animation 
      mRefreshViewImage.clearAnimation(); 
      // Hide progress bar and arrow. 
      mRefreshViewImage.setVisibility(View.GONE); 
      mRefreshViewProgress.setVisibility(View.GONE); 
    } 
  } 
   
  private void resetFooter() { 
    if(mLoadState != TAP_TO_LOADMORE) { 
      mLoadState = TAP_TO_LOADMORE; 
      // 进度条设置为不可见 
      mLoadMoreProgress.setVisibility(View.GONE); 
      // 按钮的文本替换为“加载更多” 
      mLoadMoreText.setText(R.string.loadmore_label); 
    } 
  } 
   
  private void measureView(View child) { 
    ViewGroup.LayoutParams p = child.getLayoutParams(); 
    if (p == null) { 
      p = new ViewGroup.LayoutParams( 
          ViewGroup.LayoutParams.MATCH_PARENT, 
          ViewGroup.LayoutParams.WRAP_CONTENT); 
    } 
    int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 
        0 + 0, p.width); 
    int lpHeight = p.height; 
    int childHeightSpec; 
    if (lpHeight > 0) { 
      childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); 
    } else { 
      childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 
    } 
    child.measure(childWidthSpec, childHeightSpec); 
  } 
  @Override 
  public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) { 
    // When the refresh view is completely visible, change the text to say 
    // "Release to refresh..." and flip the arrow drawable. 
    if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL 
        && mRefreshState != REFRESHING) { 
      if (firstVisibleItem == 0) {    // 如果第一个可见条目为0 
        mRefreshViewImage.setVisibility(View.VISIBLE); // 让指示箭头变得可见 
         
        if ((mRefreshHeaderView.getBottom() > mRefreshViewHeight + 20 
            || mRefreshHeaderView.getTop() >= 0) 
            && mRefreshState != RELEASE_TO_REFRESH) { 
          mRefreshViewText.setText(R.string.pull_to_refresh_release_label);// 设置刷新文本为"Release to refresh..." 
          mRefreshViewImage.clearAnimation();         // 清除动画  
          mRefreshViewImage.startAnimation(mFlipAnimation);  // 启动动画 
          mRefreshState = RELEASE_TO_REFRESH;         // 更改刷新状态为“释放以刷新" 
        } else if (mRefreshHeaderView.getBottom() < mRefreshViewHeight + 20 
            && mRefreshState != PULL_TO_REFRESH) { 
          mRefreshViewText.setText(R.string.pull_to_refresh_pull_label);// 设置刷新文本为"Pull to refresh..." 
          if (mRefreshState != TAP_TO_REFRESH) { 
            mRefreshViewImage.clearAnimation(); 
            mRefreshViewImage.startAnimation(mReverseFlipAnimation); 
          } 
          mRefreshState = PULL_TO_REFRESH; 
        } 
      } else { 
        mRefreshViewImage.setVisibility(View.GONE);     // 让刷新箭头不可见 
        resetHeader(); // 重新设置头部为原始状态 
      } 
    } else if (mCurrentScrollState == SCROLL_STATE_FLING 
        && firstVisibleItem == 0 
        && mRefreshState != REFRESHING) { 
      setSelection(1); 
    } 
    if (mOnScrollListener != null) { 
      mOnScrollListener.onScroll(view, firstVisibleItem, 
          visibleItemCount, totalItemCount); 
    } 
  } 
  @Override 
  public void onScrollStateChanged(AbsListView view, int scrollState) { 
    mCurrentScrollState = scrollState; 
    if (mOnScrollListener != null) { 
      mOnScrollListener.onScrollStateChanged(view, scrollState); 
    } 
  } 
   
  public void prepareForRefresh() { 
    resetHeaderPadding();     
    mRefreshViewImage.setVisibility(View.GONE);     // 去掉刷新的箭头 
    // We need this hack, otherwise it will keep the previous drawable. 
    mRefreshViewImage.setImageDrawable(null); 
    mRefreshViewProgress.setVisibility(View.VISIBLE);  // 圆形进度条变为可见 
    // Set refresh view text to the refreshing label 
    mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label); 
    mRefreshState = REFRESHING; 
  } 
   
  public void prepareForLoadMore() { 
    mLoadMoreProgress.setVisibility(View.VISIBLE);   
    mLoadMoreText.setText(R.string.loading_label); 
    mLoadState = LOADING; 
  } 
  public void onRefresh() { 
    Log.d(TAG, "onRefresh"); 
    if (mOnRefreshListener != null) { 
      mOnRefreshListener.onRefresh(); 
    } 
  } 
  public void OnLoadMore() { 
    Log.d(TAG, "onLoadMore"); 
    if(mOnRefreshListener != null) { 
      mOnRefreshListener.onLoadMore(); 
    } 
  } 
   
  public void onRefreshComplete(CharSequence lastUpdated) { 
    setLastUpdated(lastUpdated);  // 显示更新时间 
    onRefreshComplete(); 
  } 
   
  public void onRefreshComplete() {     
    Log.d(TAG, "onRefreshComplete"); 
    resetHeader(); 
    // If refresh view is visible when loading completes, scroll down to 
    // the next item. 
    if (mRefreshHeaderView.getBottom() > 0) { 
      invalidateViews(); 
      setSelection(1); 
    } 
  } 
  public void onLoadMoreComplete() { 
    Log.d(TAG, "onLoadMoreComplete"); 
    resetFooter(); 
  } 
   
  private class OnClickRefreshListener implements OnClickListener { 
    @Override 
    public void onClick(View v) { 
      if (mRefreshState != REFRESHING) { 
        prepareForRefresh(); 
        onRefresh(); 
      } 
    } 
  } 
   
  private class OnClickLoadMoreListener implements OnClickListener { 
    @Override 
    public void onClick(View v) { 
      if(mLoadState != LOADING) { 
        prepareForLoadMore(); 
        OnLoadMore(); 
      } 
    } 
  } 
   
  public interface OnRefreshListener { 
     
    public void onRefresh(); 
    public void onLoadMore(); 
  } 
} 

使用方法:


package com.markupartist.android.example.pulltorefresh; 
import java.text.SimpleDateFORMat; 
import java.util.Arrays; 
import java.util.Date; 
import java.util.LinkedList; 
import android.app.Activity; 
import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.widget.ArrayAdapter; 
import com.markupartist.android.widget.PullToRefreshListView; 
import com.markupartist.android.widget.PullToRefreshListView.OnRefreshListener; 
public class PullToRefreshActivity extends Activity { 
  private LinkedList<String> mListItems; 
  public static PullToRefreshListView weiboListView; 
   
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.pull_to_refresh); 
    weiboListView = (PullToRefreshListView) findViewById(R.id.weibolist); 
    // Set a listener to be invoked when the list should be refreshed. 
    weiboListView.setOnRefreshListener(new OnRefreshListener() { 
      @Override 
      public void onRefresh() { 
        // Do work to refresh the list here. 
        new GetDataTask(PullToRefreshActivity.this, 0).execute(); 
      } 
      @Override 
      public void onLoadMore() { 
        new GetDataTask(PullToRefreshActivity.this, 1).execute(); 
      } 
    }); 
    mListItems = new LinkedList<String>(); 
    mListItems.addAll(Arrays.asList(mStrings)); 
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, mListItems); 
    weiboListView.setAdapter(adapter); 
  } 
  private class GetDataTask extends AsyncTask<Void, Void, String[]> { 
    private Context context; 
    private int index; 
    public GetDataTask(Context context, int index) { 
      this.context = context; 
      this.index = index; 
    } 
    @Override 
    protected String[] doInBackground(Void... params) { 
      // Simulates a background job. 
      try { 
        Thread.sleep(2000); 
      } catch (InterruptedException e) { 
        ; 
      } 
      return mStrings; 
    } 
    @Override 
    protected void onPostExecute(String[] result) { 
      if (index == 0) { 
        // 将字符串“Added after refresh”添加到顶部 
        mListItems.addFirst("Added after refresh..."); 
        SimpleDateFormat format = new SimpleDateFormat( 
            "yyyy年MM月dd日 HH:mm"); 
        String date = format.format(new Date()); 
        // Call onRefreshComplete when the list has been refreshed. 
        weiboListView.onRefreshComplete(date); 
      } else if (index == 1) { 
        mListItems.addLast("Added after loadmore..."); 
        weiboListView.onLoadMoreComplete(); 
      } 
      super.onPostExecute(result); 
    } 
  } 
  public static String[] mStrings = { "一条微博", "两条微博", "三条微博", "四条微博", "五条微博", 
      "六条微博", "七条微博", "八条微博", "九条微博", "十条微博", "十一条微博", "十二条微博" }; 
} 

下拉刷新的那个头部布局
/2013.08.22_PullToRefresh_ListView_Demo/res/layout/pull_to_refresh_header.xml


<?xml version="1.0" encoding="utf-8"?> 
<!-- 
   Copyright (C) 2011 Johan Nilsson <http://markupartist.com> 
   Licensed under the Apache License, Version 2.0 (the "License"); 
   you may not use this file except in compliance with the License. 
   You may obtain a copy of the License at 
     http://www.apache.org/licenses/LICENSE-2.0 
   Unless required by applicable law or agreed to in writing, software 
   distributed under the License is distributed on an "AS IS" BASIS, 
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
   See the License for the specific language governing permissions and 
   limitations under the License. 
--> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:gravity="center" 
  android:paddingBottom="15dip" 
  android:paddingTop="10dip" > 
  <!-- 小型圆形进度条,初始为不可见 --> 
  <ProgressBar 
    android:id="@+id/pull_to_refresh_progress" 
    style="?android:attr/progressBarStyleSmall" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_marginLeft="30dip" 
    android:layout_marginRight="20dip" 
    android:layout_marginTop="10dip" 
    android:indeterminate="true" 
    android:visibility="gone" /> 
  <!-- 下拉刷新的那个箭头 --> 
  <ImageView 
    android:id="@+id/pull_to_refresh_image" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:layout_marginLeft="30dip" 
    android:layout_marginRight="20dip" 
    android:gravity="center" 
    android:src="@drawable/ic_pulltorefresh_arrow" 
    android:visibility="gone" /> 
  <!-- 下拉刷新的提示文本 --> 
  <TextView 
    android:id="@+id/pull_to_refresh_text" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:gravity="center" 
    android:paddingTop="5dip" 
    android:text="@string/pull_to_refresh_tap_label" 
    android:textAppearance="?android:attr/textAppearanceMedium" 
    android:textStyle="bold" /> 
  <TextView 
    android:id="@+id/pull_to_refresh_updated_at" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/pull_to_refresh_text" 
    android:layout_gravity="center" 
    android:gravity="center" 
    android:textAppearance="?android:attr/textAppearanceSmall" 
    android:visibility="gone" /> 
</RelativeLayout> 

加载更多的底部布局
/2013.08.22_PullToRefresh_ListView_Demo/res/layout/loadmore_footer.xml


<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/loadmore_layout" 
  android:layout_width="match_parent" 
  android:layout_height="wrap_content" 
  android:gravity="center" 
  android:paddingBottom="15dip" 
  android:paddingTop="10dip" > 
<!--   <Button 
    android:id="@+id/loadmore_btn" 
    android:layout_width="match_parent" 
    android:layout_height="60.0dip" 
    android:layout_centerHorizontal="true" 
    android:layout_marginTop="0.0dip" 
    android:background="@drawable/weibo_list_item_selector" 
    android:text="@string/loadmore_label" 
    android:textColor="@color/loadmore_btn_selector" 
    android:textSize="18.0sp" /> 
 --> 
  <ProgressBar 
    android:id="@+id/loadmore_progress" 
    style="?android:attr/progressBarStyleSmall" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_marginLeft="30dip" 
    android:layout_marginRight="20dip" 
    android:layout_marginTop="10dip" 
    android:indeterminate="true" 
    android:visibility="gone" /> 
  <TextView 
    android:id="@+id/loadmore_text" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:gravity="center" 
    android:paddingTop="5dip" 
    android:text="@string/loadmore_label" 
    android:textAppearance="?android:attr/textAppearanceMedium" 
    android:textStyle="bold" /> 
</RelativeLayout> 

/2013.08.22_PullToRefresh_ListView_Demo/res/layout/pull_to_refresh.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="match_parent" 
  android:orientation="vertical" > 
  <!-- 
  The PullToRefreshListView replaces a standard ListView widget. 
    自定义列表在这 
  --> 
  <com.markupartist.android.widget.PullToRefreshListView 
    android:id="@+id/weibolist" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"  
    android:cacheColorHint="#00000000" 
    android:fastScrollEnabled="true"/> 
</LinearLayout>

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

您可能感兴趣的文章:Android XListView下拉刷新和上拉加载更多Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多Android ListView下拉刷新上拉自动加载更多DEMO示例Android开发ListView中下拉刷新上拉加载及带列的横向滚动实现方法Android ListView实现上拉加载更多和下拉刷新功能Android仿XListView支持下拉刷新和上划加载更多的自定义RecyclerViewAndroid实现上拉加载更多以及下拉刷新功能(ListView)Android下拉刷新ListView——RTPullListView(demo)android开发教程之实现listview下拉刷新和上拉刷新效果android下拉刷新ListView的介绍和实现代码


--结束END--

本文标题: Android UI自定义ListView实现下拉刷新和加载更多效果

本文链接: https://www.lsjlt.com/news/23154.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android自定义ListView实现下拉刷新上拉加载更多
    目录1、创建刷新控件1.1、创建头部View1.2、下拉事件1.3、接口回调2、上拉加载更多2.1、底部样式2.2、布局添加Listview现在用的很少了,基本都是使用Recycle...
    99+
    2024-04-02
  • Android自定义实现淘宝下拉刷新效果
    要实现淘宝下拉刷新效果,可以使用RecyclerView和SwipeRefreshLayout来实现,具体步骤如下:1. 在布局文件...
    99+
    2023-08-17
    Android
  • Android怎么自定义实现下拉刷新效果
    Android中自定义实现下拉刷新效果可以通过自定义View或者使用第三方库来实现。1. 自定义View:- 创建一个继承自View...
    99+
    2023-08-18
    Android
  • Flutter listview如何实现下拉刷新上拉加载更多功能
    目录下拉刷新 RefreshIndicator 上拉加载更多 总结:下拉刷新 在Flutter中系统已经为我们提供了google material design的刷新功能 , 样式...
    99+
    2024-04-02
  • Android自定义实现顶部粘性下拉刷新效果
    本文实例为大家分享了Android实现顶部粘性下拉刷新效果的具体代码,供大家参考,具体内容如下学习:视频地址 activity_view_mv代码<?xml version="1.0" encoding="utf-8"?...
    99+
    2023-05-30
    android 顶部粘性 下拉刷新
  • Flutter实现下拉刷新和上拉加载更多
    本文实例为大家分享了Flutter实现下拉刷新和上拉加载更多的具体代码,供大家参考,具体内容如下 效果 下拉刷新 如果实现下拉刷新,必须借助RefreshIndicator,在li...
    99+
    2024-04-02
  • 原生js实现下拉刷新和上拉加载更多
    本文实例为大家分享了js实现下拉刷新和上拉加载更多的具体代码,供大家参考,具体内容如下 1.下拉刷新 由于原生js太久不用了,这里列一下此处涉及到的前置知识点: 移动端触屏事件: t...
    99+
    2024-04-02
  • Spring怎么实现上拉刷新和下拉加载效果
    这篇文章主要介绍Spring怎么实现上拉刷新和下拉加载效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!导依赖:compile 'com.android.support:recyclerview-v...
    99+
    2023-05-30
    spring
  • MUI如何实现上拉加载和下拉刷新效果
    这篇文章主要介绍了MUI如何实现上拉加载和下拉刷新效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。编写存储过程分页(此处使用T-SQL)C...
    99+
    2024-04-02
  • Flutter中怎么利用listview实现下拉刷新上拉加载更多功能
    这期内容当中小编将会给大家带来有关Flutter中怎么利用listview实现下拉刷新上拉加载更多功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。下拉刷新在Flutter中系统已经为我们提供了googl...
    99+
    2023-06-20
  • Android中怎么通过自定义控件实现下拉刷新效果
    本篇文章给大家分享的是有关Android中怎么通过自定义控件实现下拉刷新效果,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。@Override  protec...
    99+
    2023-05-30
    android
  • Android 实现的下拉刷新效果
    下面是自己实现的效果: 1、分析 可以将动画分解成: 睁眼毛驴绕着中心地球旋转,并且在到达地球中心时,切换为闭眼毛驴,最后发射出去 地球自我旋转,随着下拉而缓缓上升,达到半径距离后...
    99+
    2024-04-02
  • 原生js怎么实现下拉刷新和上拉加载更多
    本篇文章为大家展示了原生js怎么实现下拉刷新和上拉加载更多,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript是什么JS是JavaScript的简称,它是一种直译式的脚本语言,其解释器...
    99+
    2023-06-26
  • H5基于iScroll如何实现下拉刷新和上拉加载更多
    这篇文章将为大家详细讲解有关H5基于iScroll如何实现下拉刷新和上拉加载更多,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。前言   &n...
    99+
    2024-04-02
  • 微信小程序怎么实现下拉刷新和上拉加载更多
    微信小程序可以通过使用onPullDownRefresh和onReachBottom两个方法来实现下拉刷新和上拉加载更多的功能。 ...
    99+
    2024-04-03
    微信小程序
  • vue2.0中移动端如何实现下拉刷新和上拉加载更多
    这篇文章主要介绍了vue2.0中移动端如何实现下拉刷新和上拉加载更多,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。示例<templat...
    99+
    2024-04-02
  • AndroidFlutter实现自定义下拉刷新组件
    目录前言改造点DIY下拉组件样式刷新时机调整效果展示前言 在Flutter开发中官方提供了多平台的下拉刷新组件供开发者使用,例如RefreshIndicator和CupertinoS...
    99+
    2024-04-02
  • Vue vant-ui框架实现上拉加载下拉刷新功能
    目录知识点速记基本用法下拉刷新代码实现1.页面布局2.样式3.方法下拉刷新效果: 知识点速记 基本用法 List通过loading和finished两个变量控制加载状态,当组件滚动...
    99+
    2024-04-02
  • 如何使用iScroll实现下拉刷新和上滑加载效果
    这篇文章主要介绍如何使用iScroll实现下拉刷新和上滑加载效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下html代码:<!DOCTYPE html&...
    99+
    2024-04-02
  • React Native如何自定义下拉刷新上拉加载的列表
    小编给大家分享一下React Native如何自定义下拉刷新上拉加载的列表,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在移动端...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作