AdapterViewFlipper继承了AdapterViewAnimator,它会显示adapter提供的多个View组件,但它每次只能显示一个view组件,程序可以通过showPrevious()和showNext()方法控制该组件显示上一个下一个组件。AdapterViewFlipper可以在多个view切换过程中渐隐渐显的动态效果。除此之外,还可以调用startFlipper()控制它“自动播放”下一个view。

AdapterViewFlipper属性:

- android:animateFirstView:设置显示该组件的第一个View时是否使用动画

- android:inAnimation:设置组件显示时使用的动画

- android:loopViews:设置循环到最后一个组件后是否自动“转头”到第一个组件

- android:outAnimation:设置组件隐藏时使用的动画

- android:autoStart:设置显示该组件是否是自动播放

- android:flipInterval:设置自动播放的时间间隔。

```xml

xmlns:tools="http://schemas.android.com/tools"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".MainActivity">

android:id="@+id/flipper"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_alignParentTop="true"

android:flipInterval="3000">

android:id="@+id/button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="8dp"

android:layout_marginBottom="8dp"

android:onClick="prev"

android:text="上一个"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintStart_toStartOf="parent"

android:layout_marginLeft="8dp"/>

android:id="@+id/button2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginBottom="8dp"

android:onClick="next"

android:text="下一个"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintEnd_toStartOf="@+id/guideline"

app:layout_constraintStart_toStartOf="@+id/guideline"/>

android:id="@+id/button4"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginEnd="8dp"

android:layout_marginBottom="8dp"

android:layout_marginRight="8dp"

android:onClick="auto"

android:text="自动播放"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintEnd_toEndOf="parent"/>

android:id="@+id/guideline"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="vertical"

app:layout_constraintGuide_percent="0.5"/>

```

在提供的代码中,我们定义了一个 AdapterViewFliper 组件,并为三个按钮定义了事件处理方法。该实例的 Activity 采用拓展 BaseAdapter 的方式实现自己的 Adapter,并为 AdapterViewFlipper 组件设置 Adapter。以下是 Activity 代码:

```java

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends Activity implements AdapterView.OnItemClickListener {

private Button btn_flip_left, btn_flip_right, btn_flip_all;

private AdapterViewFliper adapterViewFliper;

private FlipPagerAdapter mAdapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btn_flip_left = (Button) findViewById(R.id.btn_flip_left);

btn_flip_right = (Button) findViewById(R.id.btn_flip_right);

btn_flip_all = (Button) findViewById(R.id.btn_flip_all);

adapterViewFliper = (AdapterViewFliper) findViewById(R.id.adapterview_flipper);

mAdapter = new FlipPagerAdapter();

mAdapter.setCount(30); //设置数据条数

btn_flip_left.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

adapterViewFliper.showPrevious(); //显示前一页视图

}

});

btn_flip_right.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

adapterViewFliper.next(); //下一页视图切换到后一页

}

});

btn_flip_all.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

adapterViewFliper.showNext(); //显示下一页视图,同时关闭当前页面的上一页和下一页视图

}

});

}

@Override

public void onItemClick(AdapterView parent, View view, int position, long id) {

switch (position) {

case 0: Toast.makeText(MainActivity.this, "左翻页", Toast.LENGTH_SHORT).show(); break;

case 1: Toast.makeText(MainActivity.this, "右翻页", Toast.LENGTH_SHORT).show(); break;

default: Toast.makeText(MainActivity.this, "全部翻页", Toast.LENGTH_SHORT).show(); break;

}

}

}

```

以下是重构后的内容:

```java

package com.example.myapplication;

import android.util.Log;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterViewFlipper;

import android.widget.ArrayAdapter;

import android.widget.AutoCompleteTextView;

import android.widget.BaseAdapter;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.MultiAutoCompleteTextView;

import android.widget.SimpleAdapter;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class MainActivity extends AppCompatActivity {

private int[] imageIds = new int[]{R.drawable.de, R.drawable.ds, R.drawable.ds, R.drawable.dl, R.drawable.db};

private AdapterViewFlipper flipper;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

flipper = findViewById(R.id.flipper);

//创建一个BaseAdapter对象,该对象负责提供AdapterViewFlipperTest送显示的列表项

BaseAdapter adapter = new BaseAdapter() {

@Override

public int getCount() {

return imageIds.length;

}

@Override

public Object getItem(int position) {

return position;

}

@Override

public long getItemId(int position) {

return position;

}

//该方法返回的View代表每个列表项

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ImageView imageView;

if (convertView == null) { //创建一个ImageView

imageView = new ImageView(MainActivity.this);

} else { //使用已有的ImageView实例替换convertView中的imageView实例以提高性能和减少不必要的内存分配/回收操作。这被称为视图缓存,可以避免在大量更新时出现性能问题。

imageView = (ImageView) convertView;//将现有的ImageView实例赋值给imageView变量。这样可以避免每次调用getView()方法时都创建一个新的ImageView实例。这对于性能和内存使用非常重要。因为如果我们不这样做,那么每次调用getView(),都会创建一个新的ImageView实例。这会导致大量的内存分配和回收操作,从而降低应用程序的性能并导致应用程序崩溃。因此,我们需要在适当的时候复用已经创建的视图实例。这样可以减少内存分配和回收的操作次数,从而提高应用程序的性能。同时,由于我们只使用了一次视图实例,所以也可以节省内存空间。此外,使用视图缓存还可以提高应用程序的响应速度,并降低应用程序崩溃的风险。因此,这是一个非常有用的技巧,应该在所有Android开发中广泛使用。但是需要注意的是,在使用视图缓存时,必须确保所有的视图都已经完全绘制完成之后再将其设置为复用的视图实例。否则可能会出现意外的行为。例如,当用户滚动屏幕时,可能会看到部分已经被重绘过的视图内容。为了避免这种情况的发生,我们需要在调用setContentView()方法之后再调用invalidate()方法来强制视图进行重绘。此外,我们还需要在onResume()方法中调用invalidate()方法来进行必要的布局刷新工作。这样可以确保所有的视图都被正确地初始化和绘制出来。

根据提供的内容,我们可以重构如下:

首先,我们需要创建一个自定义的AdapterViewFlipper类,然后在这个类中实现showPrevious()、showNext()方法来控制组件显示上一个、下一个组件。接下来,我们需要调用startFlipping()方法来控制自动播放效果。最后,将这些功能整合到一个程序中,并展示效果图。

以下是重构后的代码:

```java

import android.content.Context;

import android.util.AttributeSet;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterViewFlipper;

public class CustomAdapterViewFlipper extends AdapterViewFlipper {

public CustomAdapterViewFlipper(Context context) {

super(context);

}

public CustomAdapterViewFlipper(Context context, AttributeSet attrs) {

super(context, attrs);

}

public CustomAdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

/**

* 显示上一个组件

*/

public void showPrevious() {

setDisplayedChild(getDisplayedChild() - 1);

}

/**

* 显示下一个组件

*/

public void showNext() {

setDisplayedChild(getDisplayedChild() + 1);

}

}

```

在布局文件中使用这个自定义的CustomAdapterViewFlipper:

```xml

android:id="@+id/custom_adapter_view_flipper"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

```

最后,在Activity或Fragment中调用这些方法来控制组件的显示和播放效果:

```java

CustomAdapterViewFlipper customAdapterViewFlipper = findViewById(R.id.custom_adapter_view_flipper);

customAdapterViewFlipper.setAdapter(new YourAdapter()); // 将YourAdapter替换为你的实际适配器类名

customAdapterViewFlipper.showPrevious(); // 显示上一个组件的代码放在这里(可选)

customAdapterViewFlipper.showNext(); // 显示下一个组件的代码放在这里(可选)

customAdapterViewFlipper.startFlipping(); // 开始自动播放的代码放在这里(可选)

```