Android之View提升:三 使用 StackView 轮播切换多张图片

Android之View提升:三 使用 StackView 轮播切换多张图片

1. 知识点

  • BaseAdapter 的继承与使用 参考博客
    adapter是view和数据的桥梁。在一个ListView或者GridView中,你不可能手动给每一个格子都新建一个view,所以这时候就需要Adapter的帮忙,它会帮你自动绘制view并且填充数据。
  • 代码中使用,ImageAdapter继承自BaseAdapter,并且实现它的4个基础方法。
package cn.study.project.stackview;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import java.util.List;

/**
 * @author zyy
 * @date 2021年05月17日 下午9:38
 */
public class ImageAdapter extends BaseAdapter {
     

    private List<Integer> mList;
    private Context mContext;

    public ImageAdapter(List<Integer> mList, Context mContext) {
     
        this.mList = mList;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
     
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
     
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
     
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
     
        ImageView imageView=new ImageView(mContext);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setImageResource(mList.get(position));
        return imageView;
    }
}

  • 扩充:用BaseAdapter显示一个自定义布局
    首先新建一个layout,我命名为item,这个就是我们每个条目要展示的布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:orientation="horizontal" android:layout_width="match_parent"
      android:layout_height="match_parent">
      <ImageView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:srcCompat="@mipmap/ic_launcher"
          android:id="@+id/imageView" />
      <Button
          android:text="Button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/button" />
      <TextView
          android:text="TextView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:id="@+id/textView" />
LinearLayout>

接下来修改getView方法,让它显示我们这个item布局

public View getView(int position, View convertView, ViewGroup parent) {
     
      LayoutInflater inflater = LayoutInflater.from(mContext);
      View view = inflater.inflate(R.layout.item,null);
      final TextView textView = (TextView) view.findViewById(R.id.textView);
      Button button = (Button) view.findViewById(R.id.button);
      ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
      imageView.setImageResource(R.mipmap.ic_launcher);
      button.setOnClickListener(new View.OnClickListener() {
     
          @Override
          public void onClick(View v) {
     
              textView.append("!");
          }
      });
      textView.setText(data[position]);
      return view;
}

LayoutInflater是用来加载布局的,用LayoutInflater的inflate方法就可以将你的item布局绘制出来。其中getView方法中的三个参数,position是指现在是第几个条目;convertView是旧视图,就是绘制好了的视图;parent是父级视图,也就是ListView之类的。
用inflate方法绘制好后的view最后return返回给getView方法就可以了。

  • 进阶:每次返回的时候就没有使用convertView,重新创建了一个View,这样子浪费了系统资源。那要怎么利用convertView优化呢?见博客

2. 实现

效果:

实现代码:
1.界面布局:


<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/down"
            android:text="向下轮播"/>
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/up"
            android:text="向上轮播"/>
    LinearLayout>

    <StackView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:loopViews="true"
        android:id="@+id/stackView"/>
LinearLayout>
  1. 使用:
package cn.study.project.stackview;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.StackView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity {
     

    private StackView mStackView;
    private int[] myIDs={
     R.drawable.abc_0,R.drawable.abc_1,R.drawable.abc_2,R.drawable.abc_3};
    private List<Integer> myImages=new ArrayList<>();
    private Timer mTimerDown;
    private Timer mTimerUp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mStackView=findViewById(R.id.stackView);
        for (int myID : myIDs) myImages.add(myID);
        ImageAdapter adapter=new ImageAdapter(myImages,this);
        mStackView.setAdapter(adapter);
        mStackView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
     
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     
                Toast.makeText(getApplicationContext(),"eg:"+position,Toast.LENGTH_LONG).show();
            }
        });

        findViewById(R.id.down).setOnClickListener(new View.OnClickListener() {
     
            @Override
            public void onClick(View v) {
     
                if(mTimerDown!=null) mTimerDown.cancel();
                if(mTimerUp!=null) mTimerUp.cancel();
                mTimerDown=new Timer();
                mTimerDown.schedule(new TimerTask() {
     
                    @Override
                    public void run() {
     
                        runOnUiThread(new Runnable() {
     
                            @Override
                            public void run() {
     
                                mStackView.showNext();
                            }
                        });
                    }
                },0,1000);
            }
        });

        findViewById(R.id.up).setOnClickListener(new View.OnClickListener() {
     
            @Override
            public void onClick(View v) {
     
                if(mTimerDown!=null) mTimerDown.cancel();
                if(mTimerUp!=null) mTimerUp.cancel();
                mTimerUp=new Timer();
                mTimerUp.schedule(new TimerTask() {
     
                    @Override
                    public void run() {
     
                        runOnUiThread(new Runnable() {
     
                            @Override
                            public void run() {
     
                                mStackView.showPrevious();
                            }
                        });
                    }
                },0,1000);
            }
        });
    }
}

效果见上。

3. 扩展

可以使用StackView自定义Adapter轮播其他自定义控件。

你可能感兴趣的:(android,android)