IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 基于TabLayout + ViewPager2 + Fragment + 角标 实现底部导航栏(升级版) -> 正文阅读

[移动开发]Android 基于TabLayout + ViewPager2 + Fragment + 角标 实现底部导航栏(升级版)

昨天写了一篇关于导航栏的文章,由于时间太晚了没细弄,今天调整了一下主要有一下功能:

  1. 导航栏布局的自定义
  2. 使用ViewPager2默认样式
  3. 使用默认自定义样式(带角标的实现)
  4. 使用自定义样式
  5. TabLayout 导航栏在底部或者顶部
  6. 导航栏高度的调整
  7. 一些功能的延伸

效果图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

核心代码

其中的TableAndViewPage类是传入数据的bean,LogUtil类是记录日志的,替换成自己的即可。

主要方法说明:

  • TabLayout + ViewPager2 + Fragment 实现
  • 默认的加载方式是自定义的布局
  • setData() 设置数据
  • setLoadTypeToDefault() 设置加载方式为默认
  • setTabCustomLayout() 设置自定义布局
  • setTabHeight() 设置tab的高度
  • isRoll() 导航条放置在顶部,默认在底部
  • setJiaoBiaoNO() 设置角标
  • setOffscreenPageLimit() 设置预加载fragment的数量,默认懒加载

SelfViewPageFragmentControl

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.IntDef;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.widget.ViewPager2;

import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

import com.pksh.tools.R;
import com.pksh.tools.style.moudle.TableAndViewPage;
import com.pksh.tools.utils.log.LogUtil; //这时个记录日志的,替换成自己的就行

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
import java.util.List;

/**
 * 底部导航栏
 * TabLayout + ViewPager2 + Fragment 实现
 * 默认的加载方式是自定义的布局
 * setData() 设置数据
 * setLoadTypeToDefault() 设置加载方式为默认
 * setTabCustomLayout() 设置自定义布局
 * setTabHeight()  设置tab的高度
* isTop() 导航条放置在顶部,默认在底部
 * isRoll() 导航条是否可以滚动
 * setJiaoBiaoNO() 设置角标
 *
 * 2022年10月27日13:19:51
 */
public class SelfViewPageFragmentControl extends RelativeLayout{
    private static final String TAG = "底部导航栏";
    private final ViewPager2 viewPager2;
    private final TabLayout tabLayout;

    //默认加载方式
    public static final int TAB_LOAD_TYPE_DEFAULT = 0;
    //默认自定义布局
    public static final int TAB_LOAD_TYPE_DEFAULT_CUSTOM = 1;
    //自定义布局
    public static final int TAB_LOAD_TYPE_CUSTOM = 2;
    //加载方式注解
    @IntDef(value = {TAB_LOAD_TYPE_DEFAULT, TAB_LOAD_TYPE_DEFAULT_CUSTOM, TAB_LOAD_TYPE_CUSTOM}) //取值
    @Inherited
    @Target({ElementType.PARAMETER,ElementType.FIELD}) //作用域
    public @interface LoadType { }
    //导航栏加载方式
    private @LoadType int loadType = TAB_LOAD_TYPE_DEFAULT_CUSTOM;
    //数据
    private List<TableAndViewPage> data;
    //是否将导航列表放在顶部
    private boolean isTop = false;
    //是否允许导航栏滚动
    private boolean isRoll = false;
    //导航栏高度
    private int tabHeight = 0;
    //上一个选中的tab下标
    private int oldId;
    //自定义布局接口
    private TabLayoutLoadCustomView tabLayoutLoadCustomView;

    public SelfViewPageFragmentControl(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.slef_view_page_fragment, this);
        viewPager2 = findViewById(R.id.view_pager);
        tabLayout = findViewById(R.id.tab_layout);
    }

    /**
     * 创建
     */
    public void build(){
        //根据导航条位置设置布局格式
        //顶部布局
        if (isTop) {
            //设置viewPager2布局
            RelativeLayout.LayoutParams layoutParams = (LayoutParams) viewPager2.getLayoutParams();
            layoutParams.addRule(RelativeLayout.BELOW,R.id.tab_layout);
            viewPager2.setLayoutParams(layoutParams);
            //设置tablayout高度
            if (tabHeight != 0) {
                RelativeLayout.LayoutParams layoutParams1 = new LayoutParams(LayoutParams.MATCH_PARENT,tabHeight);
                tabLayout.setLayoutParams(layoutParams1);
            }
            //底部布局
        } else {
            //设置viewPager2布局
            RelativeLayout.LayoutParams layoutParams = (LayoutParams) viewPager2.getLayoutParams();
            layoutParams.addRule(RelativeLayout.ABOVE,R.id.tab_layout);
            viewPager2.setLayoutParams(layoutParams);

            //设置tablayout布局
            RelativeLayout.LayoutParams layoutParams1;
            if (tabHeight != 0) layoutParams1 = new LayoutParams(LayoutParams.MATCH_PARENT,tabHeight);
            else layoutParams1 = (LayoutParams) tabLayout.getLayoutParams();
            layoutParams1.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            tabLayout.setLayoutParams(layoutParams1);
        }

        //tabLayout是否可滚动
        if (isRoll) tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

        if (loadType != TAB_LOAD_TYPE_DEFAULT) {
            tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                //选择之后的
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
                    int selectId = tabLayout.getSelectedTabPosition();
                    oldId = selectId;
                    if (loadType == TAB_LOAD_TYPE_DEFAULT_CUSTOM &&
                            data.get(selectId).getIconSelected() != 0 &&
                            tab.getCustomView() != null) {
                        ImageView imageView = tab.getCustomView().findViewById(R.id.imageview);
                        imageView.setImageResource(data.get(selectId).getIconSelected());
                        return;
                    }

                    if (loadType == TAB_LOAD_TYPE_CUSTOM) {
                        View view = tabLayoutLoadCustomView.onTabSelected(tab, selectId);
                        if (view != null) tab.setCustomView(view);
                        return;
                    }
                    //打印日志
                    LogUtil.e(TAG,"未配置选择后的图片或者当前tab选项卡未配置自定义布局,当前加载方式:"+loadType);
                }

                //选择之前的
                @Override
                public void onTabUnselected(TabLayout.Tab tab) {
                    //自定义布局
                    if (loadType == TAB_LOAD_TYPE_DEFAULT_CUSTOM &&
                            data.get(oldId).getIcon() != 0 &&
                            tab.getCustomView() != null) {
                        ImageView imageView = tab.getCustomView().findViewById(R.id.imageview);
                        imageView.setImageResource(data.get(oldId).getIcon());
                        return;
                    }

                    if (loadType == TAB_LOAD_TYPE_CUSTOM) {
                        View view = tabLayoutLoadCustomView.onTabUnselected(tab, oldId);
                        if (view != null) tab.setCustomView(view);
                        return;
                    }
                    //打印日志
                    LogUtil.e(TAG,"未配置未选中的图片或者当前tab选项卡未配置自定义布局,当前加载方式:"+loadType);
                }
                @Override
                public void onTabReselected(TabLayout.Tab tab) {}
            });
        }

        if (data != null) {
            //设置ViewPage2的Adapter
            AdapterViewPage2 adapterViewPage = new AdapterViewPage2((FragmentActivity) getContext(),data);
            viewPager2.setAdapter(adapterViewPage);

            //tabLayout和viewPager2关联
            //smoothScroll 参数为true时点击tablayout标签会从当前页面滚动到点击的页面
            //这个参数决定了点击tab按钮fragment是懒加载还是重新加载
            new TabLayoutMediator(tabLayout, viewPager2,true,false, (tab, position) -> {
                //设置布局
                switch (loadType){
                    case TAB_LOAD_TYPE_DEFAULT:
                        if (data.get(position).getIcon() != 0) tab.setIcon(data.get(position).getIcon());
                        tab.setText(data.get(position).getText());
                        break;
                    case TAB_LOAD_TYPE_DEFAULT_CUSTOM:
                        tab.setCustomView(makeTabView(position));
                        break;
                    case TAB_LOAD_TYPE_CUSTOM:
                        View view = tabLayoutLoadCustomView.loadTabLayoutView(tab, position);
                        if (view != null) tab.setCustomView(view);
                        break;
                }
            }).attach();
        }
    }

    /**
     * 引入布局设置图标和标题
     * @param position 当前选择的选项卡
     * @return view
     */
    private View makeTabView(int position){
        @SuppressLint("InflateParams") View tabView = LayoutInflater.from(getContext()).inflate(R.layout.tab_text_icon,null);
        TextView textView = tabView.findViewById(R.id.textview);
        ImageView imageView = tabView.findViewById(R.id.imageview);
        textView.setText(data.get(position).getText());
        if (data.get(position).getIcon() != 0) imageView.setImageResource(data.get(position).getIcon());
        return tabView;
    }

    //自定义布局接口
    public interface TabLayoutLoadCustomView {
        //加载方式
        View loadTabLayoutView(TabLayout.Tab tab, int position);
        //修改后的tab
        //可在该回调中通过tab.getCustomView().findViewById(控件id)获取控件直接修改,返回NULL即可
        View onTabSelected(TabLayout.Tab tab, int position);
        //修改前的tab
        //可在该回调中通过tab.getCustomView().findViewById(控件id)获取控件直接修改,返回NULL即可
        View onTabUnselected(TabLayout.Tab tab, int position);//修改前的tab
    }

    //设置加载方式为默认
    public SelfViewPageFragmentControl setLoadTypeToDefault(){
        loadType = TAB_LOAD_TYPE_DEFAULT;
        return this;
    }

    /**
     * 设置角标
     * @param position
     * @param number
     */
    public void setJiaoBiaoNO(@IntRange(from = 0) int position, int number){
        if (position > data.size()-1) {
            LogUtil.e(TAG,"角标数字设置失败,TAB下标过大, 最大"+(data.size()-1));
            return;
        }
        if (loadType == TAB_LOAD_TYPE_DEFAULT_CUSTOM) {
            TabLayout.Tab tabAt = tabLayout.getTabAt(position);
            if (tabAt != null && tabAt.getCustomView() != null) {
                RelativeLayout relativeLayout = tabAt.getCustomView().findViewById(R.id.jiao_biao);
                if (number < 1) {
                    relativeLayout.setVisibility(GONE);
                    return;
                }
                relativeLayout.setVisibility(VISIBLE);
                TextView textView = tabAt.getCustomView().findViewById(R.id.jiao_biao_text);
                textView.setText(String.valueOf(number));
                return;
            }
            //打印日志
            LogUtil.e(TAG,"角标数字设置失败,当前tab为空或默认布局为空");
        }
        //打印日志
        LogUtil.e(TAG,"角标数字设置失败,当前加载方式不是默认布局");
    }

    //设置预加载fragment数量不包含当前页面
    public SelfViewPageFragmentControl setOffscreenPageLimit(@ViewPager2.OffscreenPageLimit int limit){
        viewPager2.setOffscreenPageLimit(limit);
        return this;
    }

    /**
     * 设置数据
     */
    public SelfViewPageFragmentControl setData(@NonNull List<TableAndViewPage> data){
        this.data = data;
        return this;
    }

    /**
     * 导航条是否在顶部
     * 根据传入的参数设置布局
     */
    public SelfViewPageFragmentControl isTop(boolean isTop){
        this.isTop = isTop;
        return this;
    }

    /**
     * 导航条是否可以滚动
     * 根据传入的参数设置布局
     */
    public SelfViewPageFragmentControl isRoll(boolean isRoll){
        this.isRoll = isRoll;
        return this;
    }

    /**
     * 设置tabLayout的高度
     */
    public SelfViewPageFragmentControl setTabHeight(@IntRange(from = 20, to = 100) int height){
        this.tabHeight = height;
        return this;
    }

    /**
     * 设置自定义view
     */
    public SelfViewPageFragmentControl setTabCustomLayout(TabLayoutLoadCustomView tabLayoutLoadCustomView){
        this.tabLayoutLoadCustomView = tabLayoutLoadCustomView;
        if (tabLayoutLoadCustomView != null) {
            this.loadType = TAB_LOAD_TYPE_CUSTOM;
        }
        return this;
    }

}

布局

TestTablayoutActivity 的布局

布局很简单就一个ViewPager2 和一个TabLayout这两个怎么放都可以,在上面代码里调整其布局
slef_view_page_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:tabTextColor="#B8B8B8"
        app:tabPaddingStart="1dp"
        app:tabPaddingEnd="1dp"
        app:tabPaddingBottom="1dp"
        app:tabPaddingTop="1dp"
        app:tabIndicatorHeight="0dp"
        app:tabSelectedTextColor="#000000"
        app:tabMinWidth="10dp"
        app:tabMaxWidth="200dp"
        app:tabPadding="0dp"

        />

</RelativeLayout>

默认自定义布局

角标的图片见文章最后附录
tab_text_icon.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/text_view_def"
    android:gravity="center">

    <RelativeLayout
        android:id="@+id/icon"
        android:layout_width="30dp"
        android:layout_height="30dp">
        <ImageView
            android:id="@+id/imageview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitCenter"
            android:padding="2dp"
            />
        <RelativeLayout
            android:id="@+id/jiao_biao"
            android:layout_width="15dp"
            android:layout_height="15dp"
            android:layout_alignParentEnd="true"
            android:visibility="gone"
            >
            <ImageView
                android:id="@+id/jiao_biao_img"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@mipmap/def_img_jiao_biao"
                />
            <TextView
                android:id="@+id/jiao_biao_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textColor="@color/text_white_color"
                android:ellipsize="end"
                android:lines="1"
                android:maxLength="2"
                android:textSize="@dimen/def_text_small_small_size" />
        </RelativeLayout>
    </RelativeLayout>

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="2dp"
        android:gravity="center"
        android:layout_gravity="center"
        android:textSize="@dimen/def_text_small_small_size"
        android:ellipsize="end"
        android:lines="1"
        android:text="1258"
        />
</LinearLayout>

Adapter

viewpage2的Adapter

AdapterViewPage2.class

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.List;

import com.pksh.tools.style.moudle.TableAndViewPage;
/**
 * TabLayout + ViewPager2 + Fragment 实现底部栏ViewPager2的Adapter
 *
 * 2022年10月27日13:23:37
 */
public class AdapterViewPage2 extends FragmentStateAdapter{

    private final List<TableAndViewPage> data;

    public AdapterViewPage2(@NonNull FragmentActivity fragmentActivity, List<TableAndViewPage> data) {
        super(fragmentActivity);
        this.data = data;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return data.get(position).getFragment();
    }

    @Override
    public int getItemCount() {
        return data.size();
    }
}

数据bean

TableAndViewPage.class

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;

/**
 * TabLayout + ViewPager2 + Fragment 实现自定义底部栏控件的module
 *
 * 2022年10月27日13:22:23
 */
public class TableAndViewPage {
    private int icon; //未选中时的图片
    private int iconSelected; //选中时的图片
    private @NonNull String text; //显示的文本
    private Fragment fragment; //关联的fragment

    public TableAndViewPage(@NonNull String text,int icon,int iconSelected,Fragment fragment){
        this.fragment = fragment;
        this.icon = icon;
        this.iconSelected = iconSelected;
        this.text = text;
    }

    public int getIcon() { return icon; }

    public void setIcon(int icon) { this.icon = icon; }

    public int getIconSelected() { return iconSelected; }

    public void setIconSelected(int iconSelected) { this.iconSelected = iconSelected; }

    public String getText() { return text; }

    public void setText(@NonNull String text) { this.text = text; }

    public Fragment getFragment() { return fragment; }

    public void setFragment(Fragment fragment) { this.fragment = fragment; }


    @Override
    public String toString() {
        return "TableAndViewPage{" +
                "icon=" + icon +
                ", iconSelected=" + iconSelected +
                ", text='" + text + '\'' +
                ", fragment=" + fragment +
                '}';
    }
}

调用

测试fragment

fragment_tab.xml文件里就一个textview这里就不贴了

public class ViewPagerFragment extends Fragment {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

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

    public static ViewPagerFragment newInstance(String label) {
        Bundle args = new Bundle();
        args.putString("label", label);
        ViewPagerFragment fragment = new ViewPagerFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onStart() {
        super.onStart();
        LogUtil.d("页面","创建fragment");
        String label = getArguments().getString("label");
        TextView text = getView().findViewById(R.id.tv_bg);
        text.setText(label);
        text.setBackgroundColor(Color.rgb((int)(Math.random() * 255), (int)(Math.random() * 255), (int)(Math.random() * 255)));
    }
}

准备数据

ViewPagerFragment.newInstance("123")参数是fragment替换为自己的fragment就行了
SelfViewPageFragmentControl selfVierPageFragmentControl = findViewById(R.id.self_view_page_1);
        List<TableAndViewPage>  data = new ArrayList<>();
        //如果不想带图片,TableAndViewPage里面的icon及iconSelected属性设置为0或者不传值即可
        data.add(new TableAndViewPage("测试1",com.pksh.tools.R.mipmap.sel_lie_biao,0,ViewPagerFragment.newInstance("123")));
        data.add(new TableAndViewPage("测试2",com.pksh.tools.R.mipmap.def_map_select,0,ViewPagerFragment.newInstance("123")));
        data.add(new TableAndViewPage("测试3",com.pksh.tools.R.mipmap.def_map_navigation_neibu,0,ViewPagerFragment.newInstance("123")));
        data.add(new TableAndViewPage("测试4",com.pksh.tools.R.mipmap.def_map_navigation_tengxun,0,ViewPagerFragment.newInstance("123")));

使用默认布局调用

默认布局可以设置角标

//      默认自定义布局加载
        selfVierPageFragmentControl.setData(data).build();
        //设置角标,仅支持默认自定义布局
        selfVierPageFragmentControl.setJiaoBiaoNO(0,45);
        selfVierPageFragmentControl.setJiaoBiaoNO(3,45);
        selfVierPageFragmentControl.setJiaoBiaoNO(1,0);

使用tabLayout原始布局加载

		//不带图片的原始布局,TableAndViewPage里面的icon设置为0即可
       selfVierPageFragmentControl.setData(data).setLoadTypeToDefault().build();

tabLayout原始布局将导航栏加载到顶部

selfVierPageFragmentControl.setData(data).isTop(true).setLoadTypeToDefault().build();

自定义tabLayout布局 并将tab放置在上面

onTabSelected() 可在该回调中通过tab.getCustomView().findViewById(控件id)获取控件直接修改,返回NULL即可
onTabUnselected()可在该回调中通过tab.getCustomView().findViewById(控件id)获取控件直接修改,返回NULL即可

selfVierPageFragmentControl.setData(data).isTop(true).setTabCustomLayout(new SelfViewPageFragmentControl.TabLayoutLoadCustomView() {
            //默认加载方式
            @Override
            public View loadTabLayoutView(TabLayout.Tab tab, int position) {
                View tabView = LayoutInflater.from(getBaseContext()).inflate(R.layout.tab_test_text,null);
                TextView textView = tabView.findViewById(R.id.test_textview);
                textView.setText(data.get(position).getText());
                tab.setCustomView(tabView);
                return null;
            }

            //更改选择后的tab
            @Override
            public View onTabSelected(TabLayout.Tab tab, int position) {
                return null;
            }
            //更改选择前的tab
            @Override
            public View onTabUnselected(TabLayout.Tab tab, int position) {
                return null;
            }
        }).build();

以上就是全部的调用方式了

附录

角标图片链接:https://lxh-customer.oss-cn-qingdao.aliyuncs.com/def_img_jiao_biao.png

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:09:06  更:2022-10-31 12:12:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 20:52:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码