Android多个TAB选项卡切换效果

2019-12-10 18:17:37王旭


解释一下上面的代码,界面中后一层为Viewpager,里面加入了多个fragment,每个fragment里面占用一个Listivew,Listview中添加一个与悬浮头高度完全一样的header,这样可显示区域就为能看到的区域,之后监听Listview的onScorll,根据当前显示的listview的item的高度来控制前一层的悬浮的位置,这个地方要注意的时,每次切换tab时,要将当前已经偏移的位置通知到当前切换的tab,比如tab1,向上滑动,影藏了悬浮头,当从tab1切换到tab2时,这是tab2的位置要向上修正,修正距离为悬浮头滑出去的距离。其他的部分代码页比较简单,看看就可以了,其次开源控件PullToRefreshListView中我修改了当在刷新时偏移的距离,当改距离通知到界面,这样在下拉刷新时,将整个头部向下偏移,

ps:上面的代码中也看到了,我们针对了不同的版本采用了不同的动画,这是由于在3.0以前,位移动画看起来移动了位置,可是实际上控件还在初始位置,为此要针对不同的版本处理不同的动画,否则tab上的点击事件在2.X版本上还是在初始位置。上面的动画采用了nineold控件,也可以自己写,这个部分动画还是比较简单的。

上面的Viewpager中添加了Fragment,我们来看看Tab1ListFragment.java

public class Tab1ListFragment extends ScrollTabHolderFragment {

  private PullToRefreshListView listView;

  private View placeHolderView;

  private ArrayAdapter<String> adapter;

  private ArrayList<String> listItems;

  private Handler handler;

  public Tab1ListFragment() {
    this.setFragmentId(PageAdapterTab.PAGE_TAB1.fragmentId);
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.page_tab_fragment_layout, container, false);
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    findViews();
    initListView();
  }

  @SuppressLint("InflateParams")
  private void findViews() {
    handler = new Handler(Looper.getMainLooper());
    listView = (PullToRefreshListView) getView().findViewById(R.id.page_tab_listview);
  }

  private void initListView() {
    setListViewListener();
    listViewAddHeader();
    listViewLoadData();
  }

  private void setListViewListener() {
    listView.setOnRefreshListener(new OnRefreshListener2<ListView>() {

      @Override
      public void onPullDownToRefresh(PullToRefreshBase<ListView> refreshView) {
        loadNews();
      }

      @Override
      public void onPullUpToRefresh(PullToRefreshBase<ListView> refreshView) {
        loadOlds();
      }

    });

    listView.setOnScrollListener(new OnScrollListener() {

      @Override
      public void onScrollStateChanged(AbsListView view, int scrollState) {
      }

      @Override
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (scrollTabHolder != null) {
          scrollTabHolder.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount, getFragmentId());
        }
      }
    });
    listView.setOnHeaderScrollListener(new OnHeaderScrollListener() {

      @Override
      public void onHeaderScroll(boolean isRefreashing, boolean istop, int value) {
        if (scrollTabHolder != null && istop) {
          scrollTabHolder.onHeaderScroll(isRefreashing, value, getFragmentId());
        }
      }
    });
  }

  private void listViewAddHeader() {
    placeHolderView = new LinearLayout(getActivity());
    AbsListView.LayoutParams params = new LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, getResources()
        .getDimensionPixelSize(R.dimen.max_header_height));
    placeHolderView.setLayoutParams(params);
    listView.getRefreshableView().addHeaderView(placeHolderView);
  }

  protected void listViewLoadData() {
    listItems = new ArrayList<String>();
    for (int i = 1; i <= 50; i++) {
      listItems.add("currnet page: " + (getFragmentId() + 1) + " item --" + i);
    }
    adapter = new ArrayAdapter<String>(getActivity(), R.layout.list_item, android.R.id.text1, listItems);
    listView.setAdapter(adapter);
    loadNews();
  }

  /**
   * 下拉清空旧的数据
   */
  private void loadNews() {
    handler.postDelayed(new Runnable() {// 模拟远程获取数据

          @Override
          public void run() {
            stopRefresh();
            // listItems.clear();
            // for (int i = 1; i <= 50; i++) {
            // listItems.add("currnet page: " + (getFragmentId() +
            // 1) + " item --" + i);
            // }
            // notifyAdpterdataChanged();
          }
        }, 300);
  }

  private void notifyAdpterdataChanged() {
    if (adapter != null) {
      adapter.notifyDataSetChanged();
    }
  }

  protected void loadOlds() {
    handler.postDelayed(new Runnable() {// 模拟远程获取数据

          @Override
          public void run() {
            stopRefresh();
            int size = listItems.size() + 1;
            for (int i = size; i < size + 50; ++i) {
              listItems.add("currnet page: " + (getFragmentId() + 1) + " item --" + i);
            }
            notifyAdpterdataChanged();
          }
        }, 300);
  }

  // PullToRefreshListView 自动添加了一个头部
  @Override
  public void adjustScroll(int scrollHeight) {
    if (scrollHeight == 0 && listView.getRefreshableView().getFirstVisiblePosition() >= 2) {
      return;
    }
    //Log.d(getTag(), "scrollHeight:" + scrollHeight);
    listView.getRefreshableView().setSelectionFromTop(2, scrollHeight);
//   Log.d(getTag(), "getScrollY:" + getScrollY(listView.getRefreshableView()));
//   handler.postDelayed(new Runnable() {
//     
//     @Override
//     public void run() {
//       Log.d(getTag(), "getScrollY:" + getScrollY(listView.getRefreshableView()));       
//     }
//   }, 5000);
  }

  public int getScrollY(AbsListView view) {
    View c = view.getChildAt(0);
    if (c == null) {
      return 0;
    }
    int top = c.getTop();
    int firstVisiblePosition = view.getFirstVisiblePosition();
    if (firstVisiblePosition == 0) {
      return -top;
    } else if (firstVisiblePosition == 1) {
      return top;
    } else {
      return -top + (firstVisiblePosition - 2) * c.getHeight() + 683;
    }
  }

  protected void updateListView() {
    if (adapter != null) {
      adapter.notifyDataSetChanged();
    }
  }

  protected void stopRefresh() {
    listView.onRefreshComplete();
  }

}