iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android多个TAB选项卡切换效果
  • 292
分享到

Android多个TAB选项卡切换效果

tabAndroid 2022-06-06 08:06:00 292人浏览 八月长安
摘要

在前一期中,我们做了悬浮头部的两个tab切换和下拉刷新效果,后来项目中要求改成三个tab,当时就能估量了一下,如果从之前的改,也不是不可以,但是要互相记住的状态就太多了,很容易

在前一期中,我们做了悬浮头部的两个tab切换和下拉刷新效果,后来项目中要求改成三个tab,当时就能估量了一下,如果从之前的改,也不是不可以,但是要互相记住的状态就太多了,很容易出现错误。就决定重新实现一下这个效果,为此先写了一个demo,这期间项目都已经又更新了两个版本了。demo还木有变成文章。

之前的版本中是采用了一个可以下拉刷新的listview,之后在listview中添加了两个头部,并且在该布局上的上面用了一个一模一样的切换tab,如果没有看过前面版本的,可以看看前一个版本,Listview多Tab上滑悬浮。

基于上述思路我们先来看看页面布局:main_activity


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="Http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/color_gray_eaeaea" >
  <android.support.v4.view.ViewPager
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
  <LinearLayout
    android:id="@+id/header"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="vertical" >
    <ImageView
      android:id="@+id/show_event_detail_bg"
      android:layout_width="fill_parent"
      android:layout_height="135dip"
      android:contentDescription="@string/empty"
      android:scaleType="fitXY"
      android:src="@drawable/header_default_bk" />
    <TextView
      android:id="@+id/show_event_detail_desc"
      android:layout_width="wrap_content"
      android:layout_height="104dip"
      android:paddingBottom="24dip"
      android:layout_marginLeft="15dip"
      android:layout_marginRight="15dip"
      android:paddingTop="25dip"
      android:text="@string/head_title_desc"
      android:textColor="@color/color_black_333333"
      android:textSize="14sp" />
    <View style="@style/horizontal_gray_divider" />
    <View style="@style/horizontal_gray_divider" />
    <com.example.refreashtabview.sliding.PagerSlidingTabStrip
      android:id="@+id/show_tabs"
      android:layout_width="match_parent"
      android:layout_height="44dip"
      android:background="@color/white" />
  </LinearLayout>
</RelativeLayout>

页面采用了两层,后面一层为Viewpager,前面为悬浮头与tab切换,在这大家应该都想到了会怎么样实现,Viewpager中添加已经fragment,每个fragment里面加入一个可下拉刷新的Listview,根据ListView的滑动来控制前一帧页面的位置。

来看看页面代码吧,MainAcitivity.java


public class MainActivity extends ActionBarActivity implements OnPageChangeListener, ScrollTabHolder {
  private PagerSlidingTabStrip tabs;
  private ViewPager viewPager;
  private SlidingPagerAdapter adapter;
  private LinearLayout header;
  private int headerHeight;
  private int headerTranslationDis;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    getHeaderHeight();
    findViews();
    setupPager();
    setupTabs();
  }
  private void findViews() {
    tabs = (PagerSlidingTabStrip) findViewById(R.id.show_tabs);
    viewPager = (ViewPager) findViewById(R.id.pager);
    header = (LinearLayout) findViewById(R.id.header);
  }
  private void getHeaderHeight() {
    headerHeight = getResources().getDimensionPixelSize(R.dimen.max_header_height);
    headerTranslationDis = -getResources().getDimensionPixelSize(R.dimen.header_offset_dis);
  }
  private void setupPager() {
    adapter = new SlidingPagerAdapter(getSupportFragmentManager(), this, viewPager);
    adapter.setTabHolderScrollingListener(this);//控制页面上滑
    viewPager.setOffscreenPageLimit(adapter.getCacheCount());
    viewPager.setAdapter(adapter);
    viewPager.setOnPageChangeListener(this);
  }
  private void setupTabs() {
    tabs.setShouldExpand(true);
    tabs.setIndicatorColorResource(R.color.color_purple_bd6aff);
    tabs.setUnderlineColorResource(R.color.color_purple_bd6aff);
    tabs.setCheckedTextColorResource(R.color.color_purple_bd6aff);
    tabs.setViewPager(viewPager);
  }
  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    tabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
  }
  @Override
  public void onPageSelected(int position) {
    tabs.onPageSelected(position);
    reLocation = true;
    SparseArrayCompat<ScrollTabHolder> scrollTabHolders = adapter.getScrollTabHolders();
    ScrollTabHolder currentHolder = scrollTabHolders.valueAt(position);
    if (NEED_RELAYOUT) {
      currentHolder.adjustScroll((int) (header.getHeight() + headerTop));// 修正滚出去的偏移量
    } else {
      currentHolder.adjustScroll((int) (header.getHeight() + ViewHelper.getTranslationY(header)));// 修正滚出去的偏移量
    }
  }
  @Override
  public void onPageScrollStateChanged(int state) {
    tabs.onPageScrollStateChanged(state);
  }
  @Override
  public void adjustScroll(int scrollHeight) {
  }
  private boolean reLocation = false;
  private int headerScrollSize = 0;
  public static final boolean NEED_RELAYOUT = Integer.valueOf(Build.VERSION.SDK).intValue() < Build.VERSION_CODES.HONEYCOMB;
  private int headerTop = 0;
  // 刷新头部显示时,没有onScroll回调,只有当刷新时会有
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount,
      int pagePosition) {
    if (viewPager.getCurrentItem() != pagePosition) {
      return;
    }
    if (headerScrollSize == 0 && reLocation) {
      reLocation = false;
      return;
    }
    reLocation = false;
    int scrollY = Math.max(-getScrollY(view), headerTranslationDis);
    if (NEED_RELAYOUT) {
      headerTop = scrollY;
      header.post(new Runnable() {
        @Override
        public void run() {
          Log.e("Main", "scorry1="+ headerTop);
          header.layout(0, headerTop, header.getWidth(), headerTop + header.getHeight());
        }
      });
    } else {
      ViewHelper.setTranslationY(header, scrollY);
    }
  }
  
  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 + headerScrollSize;
    } else if (firstVisiblePosition == 1) {
      return -top;
    } else {
      return -top + (firstVisiblePosition - 2) * c.getHeight() + headerHeight;
    }
  }
  // 与onHeadScroll互斥,不能同时执行
  @Override
  public void onHeaderScroll(boolean isRefreashing, int value, int pagePosition) {
    if (viewPager.getCurrentItem() != pagePosition) {
      return;
    }
    headerScrollSize = value;
    if (NEED_RELAYOUT) {
      header.post(new Runnable() {
        @Override
        public void run() {
          Log.e("Main", "scorry="+ (-headerScrollSize));
          header.layout(0, -headerScrollSize, header.getWidth(), -headerScrollSize + header.getHeight());
        }
      });
    }else{
      ViewHelper.setTranslationY(header, -value);
    }
  }
}


解释一下上面的代码,界面中后一层为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();
  }
}


上面代码中的界面就是xml中包含了一个PullToRefreshListView,比较简单这个地方就不贴出来了,我们看到在listViewAddHeader中,这个地方添加了一个与悬浮头等高的头部,这样就可以将内容区域给呈现出来,不会被悬浮头遮挡,其次在list的listener中我们将onScorll传到了主界面,这样Listview滚动,就可以将当前滚动的距离计算出来,修正悬浮头的距离。

我们再贴出上面剩下的代码ScrollTabHolderFragment.java与ScrollTabHolder.java


public abstract class ScrollTabHolderFragment extends Fragment implements ScrollTabHolder {
  private int fragmentId;
  protected ScrollTabHolder scrollTabHolder;
  public void setScrollTabHolder(ScrollTabHolder scrollTabHolder) {
    this.scrollTabHolder = scrollTabHolder;
  }
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount,
      int pagePosition) {
    // nothing
  }
  @Override
  public void onHeaderScroll(boolean isRefreashing, int value, int pagePosition) {
  }
  public int getFragmentId() {
    return fragmentId;
  }
  public void setFragmentId(int fragmentId) {
    this.fragmentId = fragmentId;
  }
}
public interface ScrollTabHolder {
  void adjustScroll(int scrollHeight);
  void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount, int pagePosition);
  void onHeaderScroll(boolean isRefreashing, int value, int pagePosition);
}


最后我们来看看adaper


public class SlidingPagerAdapter extends FragmentPagerAdapter {
  protected final ScrollTabHolderFragment[] fragments;
  protected final Context context;
  private SparseArrayCompat<ScrollTabHolder> mScrollTabHolders;
  private ScrollTabHolder mListener;
  public int getCacheCount() {
    return PageAdapterTab.values().length;
  }
  public SlidingPagerAdapter(FragmentManager fm, Context context, ViewPager pager) {
    super(fm);
    fragments = new ScrollTabHolderFragment[PageAdapterTab.values().length];
    this.context = context;
    mScrollTabHolders = new SparseArrayCompat<ScrollTabHolder>();
    init(fm);
  }
  private void init(FragmentManager fm) {
    for (PageAdapterTab tab : PageAdapterTab.values()) {
      try {
        ScrollTabHolderFragment fragment = null;
        List<Fragment> fs = fm.getFragments();
        if (fs != null) {
          for (Fragment f : fs) {
            if (f.getClass() == tab.clazz) {
              fragment = (ScrollTabHolderFragment) f;
              break;
            }
          }
        }
        if (fragment == null) {
          fragment = (ScrollTabHolderFragment) tab.clazz.newInstance();
        }
        fragments[tab.tabIndex] = fragment;
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      }
    }
  }
  public void setTabHolderScrollingListener(ScrollTabHolder listener) {
    mListener = listener;
  }
  @Override
  public ScrollTabHolderFragment getItem(int pos) {
    ScrollTabHolderFragment fragment = fragments[pos];
    mScrollTabHolders.put(pos, fragment);
    if (mListener != null) {
      fragment.setScrollTabHolder(mListener);
    }
    return fragment;
  }
  public SparseArrayCompat<ScrollTabHolder> getScrollTabHolders() {
    return mScrollTabHolders;
  }
  @Override
  public int getCount() {
    return PageAdapterTab.values().length;
  }
  @Override
  public CharSequence getPageTitle(int position) {
    PageAdapterTab tab = PageAdapterTab.fromTabIndex(position);
    int resId = tab != null ? tab.resId : 0;
    return resId != 0 ? context.getText(resId) : "";
  }
}


SlidingPagerAdapter 继承自FragmentPagerAdapter,从主界面传递了一个callback,将在callback传递给每个fragment,这样就将fragment与activity联系起来了。其实还有很多种方式,比如在fragment的attach中获取activity中的回调。上面代码中还有一个PageAdapterTab,它又是干什么的呐?来看看代码


public enum PageAdapterTab {
  PAGE_TAB1(0, Tab1ListFragment.class, R.string.page_tab1),
  PAGE_TAB2(1, Tab2ListFragment.class, R.string.page_tab2),
  PAGE_TAB3(2, Tab3ListFragment.class, R.string.page_tab3),
  ;
  public final int tabIndex;
  public final Class<? extends Fragment> clazz;
  public final int resId;
  public final int fragmentId;
  private PageAdapterTab(int index, Class<? extends Fragment> clazz, int resId) {
    this.tabIndex = index;
    this.clazz = clazz;
    this.resId = resId;
    this.fragmentId = index;
  }
  public static final PageAdapterTab fromTabIndex(int tabIndex) {
    for (PageAdapterTab value : PageAdapterTab.values()) {
      if (value.tabIndex == tabIndex) {
        return value;
      }
    }
    return null;
  }
}

就是一个枚举类,配置了当前要显示的fragment,这样以后就要增加就可以只修改改枚举就ok了

到此整个工程就结束了,我们截几张图看看效果:

最后在回顾一下,布局为两层,厚一层为一个Viewpager,里面包含了多个fragment,前一层为一个悬浮头与切换tab,当滑动listview时将当前显示的位置传递到主界面,同时更改主界面的位置。

代码地址如下:https://GitHub.com/FreeSunny/RefreashTabView

您可能感兴趣的文章:Android TabHost选项卡标签图标始终不出现的解决方法Android组件TabHost实现页面中多个选项卡切换效果android TabHost(选项卡)的使用方法android 选项卡(TabHost)如何放置在屏幕的底部android中TabHost的图标(48×48)和文字叠加解决方法Android控件之TabHost用法实例分析Android TabLayout(选项卡布局)简单用法实例分析Android实现底部导航栏功能(选项卡)Android仿微信底部实现Tab选项卡切换效果Android开发之TabHost选项卡及相关疑难解决方法


--结束END--

本文标题: Android多个TAB选项卡切换效果

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

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

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

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

下载Word文档
猜你喜欢
  • Android自定义选项卡切换效果
    本文实例为大家分享了Android自定义选项卡切换效果的具体代码,供大家参考,具体内容如下 一、实际使用的效果 二、自定义可切换的标题栏 1、布局 <?xml v...
    99+
    2024-04-02
  • Vue实现Tab选项卡切换
    本文实例为大家分享了Vue实现Tab选项卡切换的具体代码,供大家参考,具体内容如下 点击不同的标题显示出相应的图片 代码如下 <!DOCTYPE html> <...
    99+
    2024-04-02
  • Vue实现选项卡tab切换制作
    本文实例为大家分享了Vue实现选项卡tab切换制作代码,供大家参考,具体内容如下 1.主要的实现功能如下:(点击进行切换,这里我不做太多的样式处理了,主要看功能) 2.话不多说:主...
    99+
    2024-04-02
  • Css怎么实现tab选项卡切换
    这篇文章主要介绍了Css怎么实现tab选项卡切换,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Css实现tab选项卡切换的方法:利用target的特性,可以实现纯css的ta...
    99+
    2023-06-14
  • 如何实现js选项卡切换效果
    这篇文章主要介绍如何实现js选项卡切换效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!效果如图:具体代码:<!DOCTYPE html> <html&g...
    99+
    2024-04-02
  • Vue.js中tab怎么实现选项卡切换
    这篇文章主要介绍Vue.js中tab怎么实现选项卡切换,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下<!DOCTYPE html> <html...
    99+
    2024-04-02
  • JS怎么实现选项卡切换效果
    这篇文章主要为大家展示了“JS怎么实现选项卡切换效果”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JS怎么实现选项卡切换效果”这篇文章吧。相关代码:<!DOCTYPE html&...
    99+
    2023-06-27
  • jquery选项卡切换效果怎么实现
    要实现jQuery选项卡切换效果,可以按照以下步骤进行操作:1. 创建HTML结构,使用`ul`和`li`元素创建选项卡的导航栏,使...
    99+
    2023-08-15
    jquery
  • js选项卡切换效果的示例分析
    这篇文章主要介绍js选项卡切换效果的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下通过设置定时器实现延时0.5s切换,一个重要的技巧是定义了一个that变量来存放...
    99+
    2024-04-02
  • CSS3中怎么实现tab选项卡切换功能
    本篇文章给大家分享的是有关CSS3中怎么实现tab选项卡切换功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。CSS3伪类target利用ta...
    99+
    2024-04-02
  • angularjs实现Tab栏切换效果
    本文实例为大家分享了angularjs实现Tab栏切换效果的具体代码,供大家参考,具体内容如下 如图所示 选中后提交的实例代码: <!DOCTYPE html> <...
    99+
    2024-04-02
  • vue实现tab栏切换效果
    本文实例为大家分享了vue实现tab栏切换效果的具体代码,供大家参考,具体内容如下 一个简单的tab栏切换组件,由tabs以及tab-pane组成 效果图 使用 <templ...
    99+
    2024-04-02
  • js开发插件实现tab选项卡效果
    本文实例为大家分享了js插件实现tab选项卡效果的具体代码,供大家参考,具体内容如下 一、搭建页面 <div class="tab" data-config='{ // 在...
    99+
    2024-04-02
  • CSS如何实现简单的选项卡切换效果
    这篇文章将为大家详细讲解有关CSS如何实现简单的选项卡切换效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。   页面布局及样式:   <divclass=&q...
    99+
    2024-04-02
  • JavaScript插件如何实现Tab选项卡效果
    这篇文章将为大家详细讲解有关JavaScript插件如何实现Tab选项卡效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。首先,来看看最终效果:这是一款普通的Tab选项卡...
    99+
    2024-04-02
  • AngularJS如何实现标签页tab选项卡切换功能
    这篇文章将为大家详细讲解有关AngularJS如何实现标签页tab选项卡切换功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:选项卡一:JavaScript+h...
    99+
    2024-04-02
  • CSS文章列表切换选项卡效果如何实现
    这篇文章主要介绍了CSS文章列表切换选项卡效果如何实现,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。代码如下:<html><...
    99+
    2024-04-02
  • uniapp组件之tab选项卡滑动切换功能实现
    目录uniapp组件之tab选项卡滑动切换补充:uniapp实现tabs切换(可滑动)uniapp组件之tab选项卡滑动切换   效果如下:   代码如下:&n...
    99+
    2023-01-31
    uniapp tab选项卡滑动切换 uniapp滑动切换 uniapp tab切换 uniapp tab选项卡
  • jQuery如何实现移动端Tab选项卡效果
    小编给大家分享一下jQuery如何实现移动端Tab选项卡效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!效果图:代码如下:&l...
    99+
    2024-04-02
  • vue动态组件如何实现选项卡切换效果
    这篇文章主要介绍了vue动态组件如何实现选项卡切换效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下导航按钮:<div&n...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作