如何在Android Studio中创建一个自动滑块

287 阅读5分钟

如何在Android Studio中创建一个自动滑块

滑块出现在跨平台上,如网站页面、桌面和移动应用程序。它们通常被用来突出主屏幕上的重要功能。

一个完美的用例是一个电子商务应用程序。作为一个开发者,你想在不影响用户互动的情况下展示新产品。

幻灯片是向消费者展示此类物品的绝佳方式。

目标

本教程将教你如何在Android Studio中创建和实现滑块。

概述

以下原则将被用来创建一个滑块。

  • PagerAdapter ,将一个ArrayList 的幻灯片填充到一个ViewPager
  • 一个标签式的界面来建立一个幻灯片演示的列表。
  • 设置一个定时器任务来控制幻灯片的流动。

前提条件

要跟随本教程,对AndroidViewPagerPagerAdaptersTabLayout有一个基本的了解会有帮助。

开始学习

启动Android Studio并创建一个新的空项目。注意,我已经修改了预定义的父主题。要做同样的事情,导航到res 目录→valuesstyle.xml ,并将样式主题调整为如下所示。

<resources 
<style name="Theme.AnAutomaticAndroidSlider" parent="Theme.AppCompat.Light.DarkActionBar"></style>
</resources>

把滑块放好

继续前进,在Layout目录内创建items_layout.xml 文件。两个主要元素构成了幻灯片。

它们包括。

  • TextView显示一个标题或幻灯片的标语。
  • ImageView向用户显示一张图片。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        tools:ignore="ContentDescription,MissingConstraints"
        android:layout_width="match_parent"
        android:layout_height="245dp"
        android:scaleType="centerCrop"
        android:id="@+id/my_featured_image"
        android:src="@drawable/item1" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        app:srcCompat="@drawable/the_slider_background"
        app:layout_constraintBottom_toBottomOf="@+id/my_featured_image"
        tools:ignore="ContentDescription"
        android:id="@+id/slider_background"/>

    <TextView
        android:id="@+id/my_caption_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="The Caption Title"
        android:textColor="#ffffff"
        android:textSize="26sp"
        tools:layout_editor_absoluteX="91dp"
        tools:layout_editor_absoluteY="164dp"
        android:textAlignment="center"
        app:layout_constraintBottom_toBottomOf="@+id/slider_background"
        tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>

RecyclerView使用了一个list_item 布局。这里也适用同样的概念。一个项目布局代表了列表项目的单行。

在我们的例子中,一行将代表一个幻灯片的单一视图。项目布局是通过设置适配器对象来重用的,这些适配器对象将动态地显示数据集。

设置一个ViewPager和TabLayout

应用程序的主布局包括一个ViewPagerTabLayout ,如下面的XML代码所示。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:background="@drawable/the_slider_background"
    android:layout_height="match_parent">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/my_pager"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_width="0dp"
        android:layout_height="245dp"
        app:layout_constraintStart_toStartOf="parent"/>

    <com.google.android.material.tabs.TabLayout
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:tabGravity="center"
        android:id="@+id/my_tablayout"
        app:tabBackground="@drawable/indicator_selector"
        app:tabIndicatorHeight="0dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/my_pager">
    </com.google.android.material.tabs.TabLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

我们将把滑块布局项目填充到一个ViewPagerViewPager 是一个布局部件,它承载了几个子视图。

它也控制幻灯片的移动。一个单独的幻灯片代表每个孩子的视图。一旦我们把ViewPager 和一个PagerAdapter 连接起来,这些项目就会显示出来。

设置PagerAdapter

ViewPager 和 是相互依赖的。 控制滑块之间的移动。它还提供所有幻灯片的概览。TabLayout TabLayout

ViewPager PagerAdapter的数据来自于 。 将幻灯片存储在内存中,使得在已经加载的幻灯片之间的切换速度快如闪电。PagerAdapter PagerAdapter

在我们实现PagerAdapter ,我们需要一个模型类。

设置一个模型类

一个模型类是由数据对象的集合组成的,我们将把这些对象送入适配器。这些对象是标题图片和滑块的标题。创建一个模型类并将其命名为The_Slide_Items_Model_Class.java

在这个文件中,我们将。

  • 声明一个英雄图像的整数和一个滑块标题的字符串(变量)。
  • 生成各自的构造函数、获取器和设置器。
public class The_Slide_Items_Model_Class {

    private int featured_image;
    private String the_caption_Title;

    public The_Slide_Items_Model_Class(int hero, String title) {
        this.featured_image = hero;
        this.the_caption_Title = title;
    }

    public int getFeatured_image() {
        return featured_image;
    }

    public String getThe_caption_Title() {
        return the_caption_Title;
    }

    public void setFeatured_image(int featured_image) {
        this.featured_image = featured_image;
    }

    public void setThe_caption_Title(String the_caption_Title) {
        this.the_caption_Title = the_caption_Title;
    }
}

创建一个自定义的PagerAdapter

创建一个新的类,并将其命名为The_Slide_items_Pager_Adapter.java 。这个类应该扩展为PagerAdapter

public class The_Slide_items_Pager_Adapter extends PagerAdapter {
}

PagerAdapter 控制不同幻灯片之间的实际滑动。

为了实现PagerAdapter ,用鼠标悬停在The_Slide_items_Pager_Adapter extends PagerAdapter ,然后是right-click ,并导航到generate and import

  1. 一个The_Slide_items_Pager_Adapter 的构造函数,带有参数ContextList<The_Slide_Items_Model_Class> ,并使用this 关键字设置参数globals。
public The_Slide_items_Pager_Adapter(Context Mcontext, List<The_Slide_Items_Model_Class> theSlideItemsModelClassList) {
    this.Mcontext = Mcontext;
    this.theSlideItemsModelClassList = theSlideItemsModelClassList;
}
  1. 覆盖方法--导入以下覆盖方法。
  • instantiateItem 膨胀 布局,并通过 初始化布局中的每个项目。这通过将数据对象映射到各自的视图项目来设置各自 的位置。 方法将把这个项目列表添加到父目录中。slider root items item id ViewGroups instantiateItem ViewGroup

  • getCount 重写 将返回列表中的幻灯片数量。这将返回每个位置上的幻灯片。getCount

  • isViewFromObject 这个方法是 方法所需要的。当滑块寻呼机变为另一个滑块寻呼机时, 返回一个 作为 。这个 成为 (当前显示的滑块)。 将检查是否 ,并返回一个布尔值。如果 ,则 将被显示为当前幻灯片。instantiateItem instantiateItem Object key key View isViewFromObject View == Object true View

  • destroyItem PagerAdapter 将它所创建的每张幻灯片保存在内存中。这使得在一个滑块与另一个滑块之间的切换更快。然而,这可能需要大量的内存,特别是当你有大量的幻灯片时。对于PagerAdapter 来说,这变成了一项繁重而昂贵的任务。destroyItem 覆盖方法解决了这个问题,根据需要销毁和重新创建幻灯片。

下面是完整的The_Slide_items_Pager_Adapter 代码。

public class The_Slide_items_Pager_Adapter extends PagerAdapter {

    private Context Mcontext;
    private List<The_Slide_Items_Model_Class> theSlideItemsModelClassList;

    public The_Slide_items_Pager_Adapter(Context Mcontext, List<The_Slide_Items_Model_Class> theSlideItemsModelClassList) {
        this.Mcontext = Mcontext;
        this.theSlideItemsModelClassList = theSlideItemsModelClassList;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {

        LayoutInflater inflater = (LayoutInflater) Mcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View sliderLayout = inflater.inflate(R.layout.the_items_layout,null);

        ImageView featured_image = sliderLayout.findViewById(R.id.my_featured_image);
        TextView caption_title = sliderLayout.findViewById(R.id.my_caption_title);

        featured_image.setImageResource(theSlideItemsModelClassList.get(position).getFeatured_image());
        caption_title.setText(theSlideItemsModelClassList.get(position).getThe_caption_Title());
        container.addView(sliderLayout);
        return sliderLayout;
    }
    
    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView((View)object);
    }
    
    @Override
    public int getCount() {
        return theSlideItemsModelClassList.size();
    }
    
    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
        return view == o;
    }
}

把所有的东西挂在一起

在你的MainActivity 类中声明以下变量。

private List<The_Slide_Items_Model_Class> listItems;
private ViewPager page;
private TabLayout tabLayout;

onCreate 方法中创建一个viewPagertabLayoutIndicator 的实例。

page = findViewById(R.id.my_pager) ;
tabLayout = findViewById(R.id.my_tablayout);

准备滑块适配器

这包括。

  • 一个滑块项目的ArrayList,一张图片,以及描述每张幻灯片的标题。

查看GitHub仓库中的图片资源(drawable)。

// Make a copy of the slides you'll be presenting.
listItems = new ArrayList<>() ;
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item1,"Slider 1 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item2,"Slider 2 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item3,"Slider 3 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item4,"Slider 4 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item5,"Slider 5 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item6,"Slider 6 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item7,"Slider 7 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item8,"Slider 8 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item9,"Slider 9 Title"));
listItems.add(new The_Slide_Items_Model_Class(R.drawable.item10,"Slider 10 Title"));
  • 使用setAdapter ,将Viewpager与The_Slide_items_Pager_Adapter (PagerAdapter)挂钩。
The_Slide_items_Pager_Adapter itemsPager_adapter = new The_Slide_items_Pager_Adapter(this, listItems);
page.setAdapter(itemsPager_adapter);

这将把可用的幻灯片列表填充到pager视图中。

  • TabLayout 钩到ViewPager setupWithViewPager 。你需要一个单一的方法(setupWithViewPager)来将TabLayout 设置为ViewPager 。有了这个方法,你就可以得到一个带有表格指示器的滑动视图。
tabLayout.setupWithViewPager(page,true);

现在你可以运行该应用程序来测试一切是否正常。

SLIDERS

在屏幕上滑动会改变显示的幻灯片,而点击幻灯片的标签会改变幻灯片的页面--正如你所期望的那样。

设置定时器

创建一个名为SliderTimer 的方法,扩展到TimerTask

public class The_slide_timer extends TimerTask {
}

悬停在它上面→右键单击→生成→实现方法→run():void ,并包括以下代码块。

public class The_slide_timer extends TimerTask {
    @Override
    public void run() {

        MainActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (page.getCurrentItem()< listItems.size()-1) {
                    page.setCurrentItem(page.getCurrentItem()+1);
                }
                else
                    page.setCurrentItem(0);
            }
        });
    }
}

初始化Timer 任务,在onCreate 方法中以毫秒为单位设置delayperiod 参数。

// The_slide_timer
java.util.Timer timer = new java.util.Timer();
timer.scheduleAtFixedRate(new The_slide_timer(),2000,3000);

下面是MainActivity的完整代码。

public class MainActivity extends AppCompatActivity {
    private List<The_Slide_Items_Model_Class> listItems;
    private ViewPager page;
    private TabLayout tabLayout;

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

        page = findViewById(R.id.my_pager) ;
        tabLayout = findViewById(R.id.my_tablayout);

        // Make a copy of the slides you'll be presenting.
        listItems = new ArrayList<>() ;
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item1,"Slider 1 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item2,"Slider 2 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item3,"Slider 3 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item4,"Slider 4 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item5,"Slider 5 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item6,"Slider 6 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item7,"Slider 7 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item8,"Slider 8 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item9,"Slider 9 Title"));
        listItems.add(new The_Slide_Items_Model_Class(R.drawable.item10,"Slider 10 Title"));

        The_Slide_items_Pager_Adapter itemsPager_adapter = new The_Slide_items_Pager_Adapter(this, listItems);
        page.setAdapter(itemsPager_adapter);

        // The_slide_timer
        java.util.Timer timer = new java.util.Timer();
        timer.scheduleAtFixedRate(new The_slide_timer(),2000,3000);
        tabLayout.setupWithViewPager(page,true);
    }

    public class The_slide_timer extends TimerTask {
        @Override
        public void run() {

            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (page.getCurrentItem()< listItems.size()-1) {
                        page.setCurrentItem(page.getCurrentItem()+1);
                    }
                    else
                        page.setCurrentItem(0);
                }
            });
        }
    }
}

在你的手机上运行该应用程序,看看这是否有效。

Automatic slider timer

总结

我希望本指南能帮助你在你的应用程序中创建和实现滑块。