首页 > 其他分享 >使用ViewPager和TabLayout来实现滑动切换效果

使用ViewPager和TabLayout来实现滑动切换效果

时间:2024-07-24 23:17:51浏览次数:11  
标签:androidx ViewPager new 滑动 import android public TabLayout View

目标是创建一个Android密码输入页面,包含数字、大写字母、小写字母和特殊符号四个部分,同时支持上下滑动和左右滑动切换不同部分。

1.首先,在布局文件(activity_main.xml)中添加ViewPager和TabLayout:

<?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">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:tabIndicatorColor="@android:color/white"
        app:tabMode="scrollable" />
        
</RelativeLayout>

2.在Activity【或Fragment】中,设置ViewPager和TabLayout,并创建PagerAdapter用于管理不同部分的页面:

package com.example.password;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private TabLayout tabLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = findViewById(R.id.viewPager);
        tabLayout = findViewById(R.id.tabLayout);

        // Create an adapter that returns a fragment for each of the four sections
        viewPager.setAdapter(new SectionsPagerAdapter(getSupportFragmentManager()));

        // Connect the ViewPager with TabLayout
        tabLayout.setupWithViewPager(viewPager);

        // Set tab titles
        tabLayout.getTabAt(0).setText("数字");
        tabLayout.getTabAt(1).setText("大写字母");
        tabLayout.getTabAt(2).setText("小写字母");
        tabLayout.getTabAt(3).setText("特殊符号");
    }

    // FragmentPagerAdapter for managing fragments for each section
    private class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new DigitFragment();
                case 1:
                    return new UppercaseLetterFragment();
                case 2:
                    return new LowercaseLetterFragment();
                case 3:
                    return new SpecialCharacterFragment();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return 4; // Total number of sections
        }
    }
}

3.创建每个部分的Fragment:DigitFragment、UppercaseLetterFragment、LowercaseLetterFragment和SpecialCharacterFragment。这些Fragment分别显示数字、大写字母、小写字母和特殊字符。每个Fragment都会简单地显示一个RecyclerView,用于显示对应的密码字符或者按钮。

package com.example.password;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class DigitFragment extends Fragment {

    private RecyclerView recyclerView;
    private PasswordAdapter adapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_password, container, false);

        recyclerView = rootView.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3)); // Grid layout with 3 columns
        adapter = new PasswordAdapter(generateDigitList());
        recyclerView.setAdapter(adapter);

        return rootView;
    }

    private List<String> generateDigitList() {
        List<String> digits = new ArrayList<>();
        for (int i = 0; i <= 9; i++) {
            digits.add(String.valueOf(i));
        }
        return digits;
    }
}
package com.example.password;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class UppercaseLetterFragment extends Fragment {

    private RecyclerView recyclerView;
    private PasswordAdapter adapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_password, container, false);

        recyclerView = rootView.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3)); // Grid layout with 3 columns
        adapter = new PasswordAdapter(generateUppercaseList());
        recyclerView.setAdapter(adapter);

        return rootView;
    }

    private List<String> generateUppercaseList() {
        List<String> uppercaseLetters = new ArrayList<>();
        for (char c = 'A'; c <= 'Z'; c++) {
            uppercaseLetters.add(String.valueOf(c));
        }
        return uppercaseLetters;
    }
}
package com.example.password;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class LowercaseLetterFragment extends Fragment {

    private RecyclerView recyclerView;
    private PasswordAdapter adapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_password, container, false);

        recyclerView = rootView.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3)); // Grid layout with 3 columns
        adapter = new PasswordAdapter(generateLowercaseList());
        recyclerView.setAdapter(adapter);

        return rootView;
    }

    private List<String> generateLowercaseList() {
        List<String> lowercaseLetters = new ArrayList<>();
        for (char c = 'a'; c <= 'z'; c++) {
            lowercaseLetters.add(String.valueOf(c));
        }
        return lowercaseLetters;
    }
}
package com.example.password;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class SpecialCharacterFragment extends Fragment {

    private RecyclerView recyclerView;
    private PasswordAdapter adapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_password, container, false);

        recyclerView = rootView.findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 3)); // Grid layout with 3 columns
        adapter = new PasswordAdapter(generateSpecialCharacterList());
        recyclerView.setAdapter(adapter);

        return rootView;
    }

    private List<String> generateSpecialCharacterList() {
        List<String> specialCharacters = new ArrayList<>();
        // Add commonly used special characters here, adjust as per your requirements
        specialCharacters.add("!");
        specialCharacters.add("@");
        specialCharacters.add("#");
        specialCharacters.add("$");
        specialCharacters.add("%");
        specialCharacters.add("&");
        specialCharacters.add("*");
        specialCharacters.add("-");
        specialCharacters.add("+");
        specialCharacters.add("=");

        return specialCharacters;
    }
}

4.共用的 RecyclerView 适配器 PasswordAdapter.java

package com.example.password;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.PasswordViewHolder> {

    private List<String> dataList;

    public PasswordAdapter(List<String> dataList) {
        this.dataList = dataList;
    }

    @NonNull
    @Override
    public PasswordViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_password, parent, false);
        return new PasswordViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PasswordViewHolder holder, int position) {
        String item = dataList.get(position);
        holder.textView.setText(item);
    }

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

    static class PasswordViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        PasswordViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.text_view_item);
        }
    }
}

5.每个Fragment中,根据需要创建布局和逻辑来显示对应的密码字符。

 布局文件 fragment_password.xml

该布局文件用于每个Fragment中RecyclerView的布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    android:clipToPadding="false"
    android:scrollbars="vertical" />

布局文件 item_password.xml

该布局文件用于RecyclerView中每个项的布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_view_item"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:textSize="18sp"
    android:background="?attr/selectableItemBackground"
    android:textColor="@android:color/black"
    android:gravity="center"
    android:textAppearance="?android:attr/textAppearanceListItem" />

 

现在展示出的页面如下

 

 

那如果我们需要再给tab行下面加一个输入框【要在每个标签下方添加一个输入框】 ,并添加回退、清理和确定按钮。

也就是说:每个标签页(Tab)上方有一个显示密码规则的区域(例如数字、大写字母、小写字母、特殊字符),下方是一个固定的输入框和三个按钮(回退、清理、确定),切换标签页时,下方的输入框和按钮保持不变,只是上方的密码规则区域内容变化。

这样我们可以采用TabLayoutViewPager 的组合来实现,每个标签页对应一个 Fragment,下方的输入框和按钮放在一个单独的布局中,使其在切换标签页时保持不变。

 1.更改布局文件 activity_main.xml
<?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">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="6dp"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.MaterialComponents.ActionBar" />

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tab_layout" />

    <LinearLayout
        android:id="@+id/password_controls_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true"
        android:padding="16dp">

        <EditText
            android:id="@+id/edit_text_password"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:hint="Enter password"
            android:inputType="textPassword" />

        <Button
            android:id="@+id/button_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Back" />

        <Button
            android:id="@+id/button_clear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Clear" />

        <Button
            android:id="@+id/button_confirm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Confirm" />

    </LinearLayout>

</RelativeLayout>

2.修改MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {

    private EditText editTextPassword;
    private Button buttonBack, buttonClear, buttonConfirm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editTextPassword = findViewById(R.id.edit_text_password);
        buttonBack = findViewById(R.id.button_back);
        buttonClear = findViewById(R.id.button_clear);
        buttonConfirm = findViewById(R.id.button_confirm);

        ViewPager viewPager = findViewById(R.id.view_pager);
        TabLayout tabLayout = findViewById(R.id.tab_layout);

        // Set up ViewPager with adapter
        PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(pagerAdapter);
        tabLayout.setupWithViewPager(viewPager);

        buttonBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!editTextPassword.getText().toString().isEmpty()) {
                    String currentText = editTextPassword.getText().toString();
                    editTextPassword.setText(currentText.substring(0, currentText.length() - 1));
                }
            }
        });

        buttonClear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                editTextPassword.setText("");
            }
        });

        buttonConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String password = editTextPassword.getText().toString();
                // Example: validatePassword(password);
                Toast.makeText(MainActivity.this, "Password entered: " + password, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private class PagerAdapter extends FragmentPagerAdapter {

        private final String[] tabTitles = new String[]{"Digits", "Uppercase", "Lowercase", "Special"};

        public PagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new DigitFragment();
                case 1:
                    return new UppercaseLetterFragment();
                case 2:
                    return new LowercaseLetterFragment();
                case 3:
                    return new SpecialCharacterFragment();
                default:
                    return null;
            }
        }

        @Override
        public int getCount() {
            return tabTitles.length;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return tabTitles[position];
        }
    }
}

 

3.更新 Fragment 类

更新每个标签页的 Fragment 类【DigitFragmentUppercaseLetterFragmentLowercaseLetterFragmentSpecialCharacterFragment】,使用新的布局文件,并在 Fragment 中查找并设置输入框和按钮的点击事件。

 

在实现左右滑动的同时,如果需要支持上下滑动,可以采用每个tab页的内容使用了ListView来实现垂直滚动,而整体的tab切换使用了TabBar和TabBarView来管理

标签:androidx,ViewPager,new,滑动,import,android,public,TabLayout,View
From: https://www.cnblogs.com/yddbkdz/p/18321999

相关文章

  • 单调队列-滑动窗口最大值
    题目:给你一个整数数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的k个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。思路:通过双端队列,因为只看得到k个数字,所以先在队列放入k个数字,并且每次放入时都要将他与......
  • 算法——滑动窗口(day7)
    904.水果成篮 904.水果成篮-力扣(LeetCode) 题目解析:根据题意我们可以看出给了我们两个篮子说明我们在开始采摘到结束的过程中只能有两种水果的种类,又要求让我们返回收集水果的最大数目,这不难让我们联想到题目的另一层意思:求最长连续子数组,条件为不超过两种水果种类。......
  • 用python制作终端向上滑动的效果
    我正在开发一个项目,需要时需要过渡效果。我正在通过CRT终端模拟器“cool-retro-term”运行这个python项目。我想让它像老式CRT终端一样,屏幕平滑地向上滑动所有字符以呈现下一行或刷新屏幕。像这样:终端滑动效果不是单独打印的字符,而是屏幕的滚动。到目......
  • 代码随想录数组二刷:长度最小的子数组(滑动窗口)
    代码随想录数组二刷:长度最小的子数组(滑动窗口)leetcode209这道题采用滑动窗口的思想去做。实现滑动窗口,主要确定如下三点:窗口内是什么?如何移动窗口的起始位置?如何移动窗口的结束位置?窗口就是满足其和≥s的长度最小的连续子数组。窗口的起始位置如何移动:如果当前窗口......
  • Windows图形界面(GUI)-DLG-C/C++ - 滑动条(Trackbar)
    公开视频-> 链接点击跳转公开课程博客首页-> ​​​​​​链接点击跳转博客主页目录滑动条(Trackbar)使用场景初始控件控件消息示例代码滑动条(Trackbar)使用场景音量控制亮度调节视频播放进度控制任何需要用户在特定范围内选择值的场景初始控件TBM_......
  • 算法篇 滑动窗口 leetCode 水果成篮
    水果成蓝1.题目描述2.图形分析2.1原理解释2.2怎么想出使用滑动窗口2.3图形分析3.代码演示1.题目描述2.图形分析2.1原理解释2.2怎么想出使用滑动窗口2.3图形分析3.代码演示......
  • day2 双指针与滑动窗口
    任务977.有序数组的平方给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。思路由于平方后最大值只可能出现在左右两边,所以每次取左右两边的较大值加入到新数组的尾部。故采用双指针法,一个指向尾部,一个指向头部,每次取符合条件......
  • uniapp(全端兼容) - 最新详细实现 “卡片式堆叠“ 轮播图效果,堆叠在一起的轮播图片可
    效果图在uni-app微信小程序/手机h5网页网站/安卓app/苹果app/支付宝小程序/nvue等(全平台完美兼容)开发中,实现uniApp各端都兼容的图片堆叠轮播图功能,层叠轮播插件,详细实现上下层叠轮播图并且在全平台通用兼容,卡片叠加在一起的轮播翻滚,错开叠加来回拖曳左右滚动切换,支持修改......
  • OpenCV窗口交互(窗口滑动条,鼠标响应)
    窗口交互操作#####(1)图像窗口滑动条​Open-CV中创建滑动条函数原型为:intcreateTrackbar(constString&trackbarname,constString&winname,int*value,intcount,TrackbarCallbackonChange=......
  • 代码随想录算法训练营第十一天 | 150. 逆波兰表达式求值、 239. 滑动窗口最大值、347.
    150.逆波兰表达式求值题目:.-力扣(LeetCode)思路:遇到数字进栈,遇到符号出栈运算。代码:classSolution{public:intevalRPN(vector<string>&tokens){stack<longlong>sta;for(strings:tokens){if(s=="+"||s=="-"||s=="*"......