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入门系列(三):高级组件 -> 正文阅读

[移动开发]Android入门系列(三):高级组件

一、高级组件

1.自动完成文本框AutoCompleteTextView

有以下常用xml属性

android:completionHint用于为弹出的下拉菜单指定标题

android:completionThreshold指定用户输入至少几个字符开始提示

android:dropDownHeigh/Weightt指定下拉菜单高度和宽度

android:popupBackground指定下拉菜单的背景

xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <AutoCompleteTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/autoview"
        android:completionThreshold="2"
        android:layout_weight="3"/>
    <Button
        android:id="@+id/get"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取内容"
        android:layout_weight="1"
        android:layout_marginLeft="10dp"/>

</LinearLayout>

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Toast;

import androidx.annotation.Nullable;


import com.thundersoft.session1.R;

public class AutoViewActivity extends Activity {
    static final String[] strings = new String[]{"aadfdfdf","aawerwewe","aaxcxx","aawerw","aadfcv","aa123123"};
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.autocompletetextview);

        AutoCompleteTextView textView = findViewById(R.id.autoview);
        Button get = findViewById(R.id.get);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, strings);
        textView.setAdapter(adapter);

        get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(AutoViewActivity.this, textView.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });


    }
}

java代码中,定义了一个static final类的字符串,接着在oncreate中定义数组适配器,将字符串放进适配器并且加载,就可完成提示

虚拟机可以增加中文语言,也可以输入中文字符串测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Im9ZAplA-1637733437881)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123215058463.png)]

2.进度条ProgressBar

后台进行前台现实,引出进度条

进度条的xml属性

android:max 一般为100,即进度条的最大值

android:progress 指定进度条的值,通常在java里和线程相关联

android:progressDrawable 设置进度条的轨道形式

进度条的style风格

?android:attr/progressBarStyleHorizontal细长条

?android:attr/progressBarStyleLarge/Small大/小圆形

@android:style/Widget.ProgressBar.Large/Small大/小跳远、旋转画面的进度条

@android:style/Widget.ProgressBar.Horizontal粗长条

xml代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <AutoCompleteTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/autoview"
        android:completionThreshold="2"
        android:layout_weight="3"/>
    <Button
        android:id="@+id/get"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取内容"
        android:layout_weight="1"
        android:layout_marginLeft="10dp"/>

</LinearLayout>

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class ProgressBarActivity extends Activity {
    private int status = 0;
    private Handler handler;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progressbar);

        ProgressBar bar1 = findViewById(R.id.bar1);
        ProgressBar bar2 = findViewById(R.id.bar2);

        handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if (msg.what==0x111){
//                    更新进度
                    bar1.setProgress(status);
                    bar2.setProgress(status);
                }else {
                    Toast.makeText(ProgressBarActivity.this, "操作完成", Toast.LENGTH_SHORT).show();
//                    进度条完成后消失并且不占用空间
                    bar1.setVisibility(View.GONE);
                    bar2.setVisibility(View.GONE);
                }
            }
        };
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
//                    得到完成耗时工作的百分比
                    status = doWork();
                    Message message = new Message();
                    if (status<100){
                        message.what=0x111;
//                        发送信息
                        handler.sendMessage(message);
                    }else {
                        message.what=0x110;
                        handler.sendMessage(message);
                        break;
                    }
                }
            }
            int doWork(){
//                改变完成进度
                status += Math.random()*10;
                try{
//                    休眠200mx
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return status;
            }
//            线程开启
        }).start();
    }
}

定义一个处理消息的handler对象,在oncreate方法中,利用匿名内部类来实例化处理消息的handler对象,重写了其中的handleMessage方法,实现了耗时操作没有完成的时候就更新进度,否则就进度条不显示

message.what=0x111相当于一个case,what即为case的条件,它是为了判断what的值来进行相应操作,相当于一个判断中间值

线程方面,每一次dowork方法status都会增加0~1乘以10,接着暂停0.2s,当status小于100时就会发送0x111的消息,否则发送0x110的消息,如果是0x111就通过setProgress操作更新progressbar,否则就让进度条消失并且显示toast

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pOkccjTW-1637733437883)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123214948120.png)]

不过我们可以使用AsyncTask来更加好的控制进程

下面演示了进度条完成后加载图片的一系列操作

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/linearlayout">
    <ProgressBar
    android:id="@+id/bartest"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:max="100"/>

</LinearLayout>
package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class Test1Activity extends Activity {
    private int image[] = new int[]{R.drawable.jpg1,R.drawable.jpg2,R.drawable.jpg3,R.drawable.jpg4,R.drawable.jpg5};
    private LinearLayout linearLayout;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_PROGRESS);
        setContentView(R.layout.test1);
        linearLayout = findViewById(R.id.linearlayout);
        progressBar = findViewById(R.id.bartest);

        new MyTack().execute();
    }
//    三个参数应该分别是,启动任务前输入的参数、后台任务完成的进度值类型,执行完成后返回的结果类型
    class MyTack extends AsyncTask<Void,Integer,LinearLayout>{
//        耗时操作前被调用,通常用来初始化一些操作
//        @Override
//        protected void onPreExecute() {
            显示进度条
            progressBar.setProgress(0);
//            super.onPreExecute();
//        }
//        要执行的任务
        @Override
        protected LinearLayout doInBackground(Void... params) {
            LinearLayout layout = new LinearLayout(Test1Activity.this);
            for (int i = 1; i < image.length+1; i++) {
                ImageView imageView = new ImageView(Test1Activity.this);
                imageView.setLayoutParams(new ViewGroup.LayoutParams(200,200));
                imageView.setImageResource(image[i-1]);
                    try {
                        layout.addView(imageView);
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                publishProgress(i);
            }
            return layout;
        }
//        publishProgress
        @Override
        protected void onProgressUpdate(Integer... values) {
            progressBar.setProgress(values[0]*20);
            super.onProgressUpdate(values);
        }
        @Override
        protected void onPostExecute(LinearLayout result) {
            progressBar.setVisibility(View.GONE);
//            setProgressBarVisibility(false);
            linearLayout.addView(result);
            super.onPostExecute(result);
        }
}
}

可以见得,这里通过了建立了一个内部类的匿名对象来调用execute方法执行AsyncTask里的内容

而这个内部类继承了AsyncTask需要传入几个参数,重写几个方法

查看AsyncTask源码,可以看到它的形参是AsyncTask<Params, Progress, Result>

? Params代表着启动任务执行的输入参数的类型,在这里,直接启动不需要任务执行则为void

? Progress代表着后台完成的进度条类型,这里是int的包装类

? Result是结束后返回的类型,返回给了线性布局

参数解决了,接下来是方法,这里重写了四个方法,分别是onPreExecute,doInBackground,onProgressUpdate和onPostExecute

? onPreExecute指的是在线程启动前被调用,里面写一些初始化的方法,因为这里使用的是xml的progressbar,所以可以不用重写这个方法(自带的propressbar看不清,实在是太小了)

? doInBackground在AsyncTask中是abstract方法,一定要被实现,它的内容是后台线程将要完成的任务。这里的任务就是循环图片数组,然后放进imageview中,每放一张sleep一段时间,但是这个过程需要被观察到,于是就要通过publishProgress(i);来更新进度条

? onProgressUpdate就是每次publishProgress(i)来执行的代码,每次更新就更新进度条进度

? onPostExecute是线程完成时自动启用的方法,这里的进度条完成后将进度条给取消显示,接着显示图片内容

最后通过new MyTack().execute();来执行这四个步骤方法完成显示

需要注意的是,异步任务只能被执行一次

不过这个进度条是在标题栏外面的,如果想让标题栏在进度条里面需要用到自定义标题栏

写一个自定义的标题xml,把之前另外一个线性布局的进度条剪贴过来

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="定制的标题栏"
        android:textStyle="bold"
        android:textColor="#FFFF0000"
        />
    <ProgressBar
        android:id="@+id/bartest"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"
        android:max="100"/>
</LinearLayout>

需要自定义一下主题还有在清单文件里更改主题

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <style name="TitleBackgroundColor">
        <item name="android:background">#00BFFF</item>
    </style>
    <style name="titlestyle" parent="android:Theme" >
         <item name="android:windowTitleSize">40dip</item>
         <item name="android:windowTitleBackgroundStyle">@style/TitleBackgroundColor</item>
     </style>
 </resources>
android:theme="@style/titlestyle" >

java更改如下代码即可

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.test1);

    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.title);
    linearLayout = findViewById(R.id.linearlayout);
    progressBar = findViewById(R.id.bartest);

    new MyTack().execute();
}

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

3.拖动条和星级评分条SeekBar RatingBar

拖动条的xml和java代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/seekbar"
        android:max="100"
        android:padding="20dp"
        />
    <TextView
        android:id="@+id/info1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="提示信息1"
        android:textSize="20dp"/>
    <TextView
        android:id="@+id/info2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="提示信息2"
        android:textSize="20dp"/>
</LinearLayout>
package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class SeekRatingBarActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.seekratingbar);

        SeekBar seekBar=findViewById(R.id.seekbar);
        TextView info1=findViewById(R.id.info1);
        TextView info2=findViewById(R.id.info2);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
//            发生滑动执行方法
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                String s = String.valueOf(progress);
                info1.setText(s);
            }

            @Override
//            开始改变时执行方法
            public void onStartTrackingTouch(SeekBar seekBar) {
                info2.setText("开始滑动");
            }

            @Override
//            结束改变时执行方法
            public void onStopTrackingTouch(SeekBar seekBar) {
                info2.setText("停止滑动");
            }
        });
    }
}

Seekbar空间的监听器方法需要重写三个方法

值得注意的是Textview里不能传入int否则会报错,需要转换为Sring类型

星级评分条xml如下

<RatingBar
    android:id="@+id/ratingbar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:isIndicator="false"
    android:numStars="5"
    android:rating="3.5" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="提交"
    android:id="@+id/submit"/>

nubStars为星星数量,rating是初始星星,isindicator设置为false表示可以更改

RatingBar ratingBar = findViewById(R.id.ratingbar);
Button submit = findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ratingBar.setStepSize(1);
        float rating = ratingBar.getRating();
        String s1 = String.valueOf((int)rating);
        Toast.makeText(SeekRatingBarActivity.this,  s1, Toast.LENGTH_SHORT).show();
    }
});

注意转换为String

另外ratingBar还有getProgress获取进度方法,getStepSize获取每个最少改变多少个星级

ratingBar.setStepSize(1);可以放在oncreate当中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-47BhhBSd-1637733437887)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123214901078.png)]

4.选项卡TabHost

tabhost的xml有几点需要注意

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:id="@android:id/tabhost"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TabWidget
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@android:id/tabs"/>
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@android:id/tabcontent"/>
    </LinearLayout>



</TabHost>

TabHost作为总标签,且TabHost和TabWidget与FrameLayout的id必须固定,且一定要是@android的这种写法

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.TabHost;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class TableHostActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabhost);

        TabHost tabhost = findViewById(android.R.id.tabhost);
//        初始化
        tabhost.setup();

        LayoutInflater from = LayoutInflater.from(this);
        from.inflate(R.layout.tab1,tabhost.getTabContentView());
        from.inflate(R.layout.tab2,tabhost.getTabContentView());

        tabhost.addTab(tabhost.newTabSpec("tab1")
                .setIndicator("第一个页面")
                .setContent(R.id.l1));
        tabhost.addTab(tabhost.newTabSpec("tab2")
                .setIndicator("第二个页面")
                .setContent(R.id.l2));
    }
}

其中,tab1和tab2是两个页面中的xml文件,l1和l2是这两个xml的布局id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fCgZ6R2N-1637733437890)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123214815303.png)]

5.图像切换器ImageSwitche

图像切换器需要建立图像工厂,xml文件如下

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


    <ImageSwitcher
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageswitcher"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一张"
            android:id="@+id/before"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下一张"
            android:id="@+id/after"/>
    </LinearLayout>
</LinearLayout>

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ViewSwitcher;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class ImageSwitcherActivity extends Activity {
    int index = 0;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        int[] image = new int[]{R.drawable.jpg1,R.drawable.jpg2,R.drawable.jpg3,R.drawable.jpg4,R.drawable.jpg5};

        super.onCreate(savedInstanceState);
        setContentView(R.layout.imageswitcher);

        ImageSwitcher imageSwitcher = findViewById(R.id.imageswitcher);
        imageSwitcher.setInAnimation(AnimationUtils.loadAnimation(ImageSwitcherActivity.this, android.R.anim.fade_in));
        imageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(ImageSwitcherActivity.this, android.R.anim.fade_out));
        imageSwitcher.setFactory(
                new ViewSwitcher.ViewFactory() {
                    @Override
                    public View makeView() {
                        ImageView imageView = new ImageView(ImageSwitcherActivity.this);
                        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                        imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
                                ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT
                        ));
                        return imageView;
                    }
                }
        );
//        默认显示的图片
        imageSwitcher.setImageResource(image[index]);
        Button before = findViewById(R.id.before);
        Button after = findViewById(R.id.after);
        before.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (index > 0 ){
                    index --;
                }else {
                    index = image.length - 1;
                }
                imageSwitcher.setImageResource(image[index]);
            }
        });
        after.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (index < image.length - 1 ){
                    index ++;
                }else {
                    index = 0;
                }
                imageSwitcher.setImageResource(image[index]);
            }
        });
    }
}

优先定义image的图片数组,以及一个为0的index坐标,找到imageSwitcher的id并且新建对象,设置它的渐入渐出的动画

并且设置它的工厂对象,新建一个ViewFactory的工厂对象重写makeView方法,在方法里实例化一个imageview对象,为这个对象设置位置的大小,并返回

设置默认显示的图片,并且设置点击事件,每一次点击重设显示图像功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KBX74GLe-1637733437892)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123214733511.png)]

6.网格视图GridView

网格视图有以下xml属性

android:columnWidth用于设置每一列的宽度

android:verticalSpacing/horizontalSpacing用于设置各元素之间的垂直/水平间距

android:numColumns设置列数,通常大于一,如果为一建议使用ListView

android:stretchMode设置拉伸模式

? none不拉伸

? spacingWidth仅拉伸元素之间的间距

? columnWidth仅拉伸表格元素本身

? spacingWidthUniform表格元素本身和元素之间的间距一起拉伸

演示xml如下

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

    <GridView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchMode="columnWidth"
        android:numColumns="3"
        android:id="@+id/gridview"/>

</LinearLayout>

同时还要设置每一个格子的view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:id="@+id/imageview"
        android:scaleType="fitXY"
        android:paddingLeft="10px"
        />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5px"
        android:layout_gravity="center"
        android:id="@+id/titleview"/>

</LinearLayout>

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.os.Bundle;
import android.widget.GridView;
import android.widget.SimpleAdapter;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class GridViewActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gridview);

        GridView gridView = findViewById(R.id.gridview);
        int[] image = new int[]{R.drawable.jpg1,R.drawable.jpg2,R.drawable.jpg3,R.drawable.jpg4,R.drawable.jpg5};
        String[] title = {"头像1", "头像2", "头像3", "头像4", "头像5"};
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < title.length; i++) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("imageview",image[i]);
            map.put("titleview",title[i]);
            list.add(map);
        }
        SimpleAdapter simpleAdapter = new SimpleAdapter(this,
                list,
                R.layout.items,
                new String[]{"titleview", "imageview"},
                new int[]{R.id.titleview, R.id.imageview});
        gridView.setAdapter(simpleAdapter);
    }
}

使用simpleAdapter适配器配置图片和文字,以上内容见上一篇的列表视图的适配器解释

也可以使用BaseAdapter适配器

BaseAdapter baseAdapter = new BaseAdapter(){

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView==null){
            imageView = new ImageView(com.thundersoft.chapter2.GridViewActivity.this);
            imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
            imageView.setPadding(5,0,5,0);
        }else {
            imageView=(ImageView) convertView;
        }
        imageView.setImageResource(image[position]);
        return imageView;
    }
};
gridView.setAdapter(baseAdapter);

通过new一个BaseAdapter对象,重写其中的方法

getView方法中,如果convertView为空的话,就是这imageview,为它设置缩放方式和内边距,并且设置显示图片

getItemId是获得当前选项id的方法

getItem是获得当前选项的方法

getCount是获得当前数量方法

也就是说,BaseAdapter自己通过java代码的方式新建了每一个网格布局

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9a8WvSF9-1637733437894)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123214457896.png)]

7.画廊视图Gallery

画廊视图有点类似于一个看图片的软件,可以左右切换,它有一下主要的xml属性

android:animationDuration用于设置列表项切换时的动画时间

android:spacing用于设置列表项之间的间距

android:unselectedAlpha用于设置没有选中的列表项的透明度

示例xml如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Gallery
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/gallery"
        android:spacing="20px"
        android:unselectedAlpha="0.3"
        />
</LinearLayout>

java代码如下

package com.thundersoft.chapter2;

import android.app.Activity;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.thundersoft.session1.R;

public class GalleryActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery);

        int[] image = new int[]{R.drawable.jpg1,R.drawable.jpg2,R.drawable.jpg3,R.drawable.jpg4,R.drawable.jpg5};
        Gallery gallery = findViewById(R.id.gallery);

        BaseAdapter baseAdapter = new BaseAdapter(){
            @Override
            public int getCount() {
                return image.length;
            }
            @Override
            public Object getItem(int position) {
                return position;
            }
            @Override
            public long getItemId(int position) {
                return position;
            }
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ImageView imageView;
                if (convertView==null){
                    imageView = new ImageView(com.thundersoft.chapter2.GalleryActivity.this);
                    imageView.setScaleType(ImageView.ScaleType.FIT_XY);
                    imageView.setPadding(5,0,5,0);
//                    新加的
                    imageView.setLayoutParams(new Gallery.LayoutParams(400,350));
                    TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
                    imageView.setBackgroundResource(typedArray.getResourceId(
                            R.styleable.Gallery_android_galleryItemBackground,0
                    ));
                }else {
                    imageView=(ImageView) convertView;
                }
                imageView.setImageResource(image[position]);
                return imageView;
            }
        };

        gallery.setAdapter(baseAdapter);
        gallery.setSelection(image.length/2);
        gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(GalleryActivity.this, String.valueOf(position+1), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这里使用的baseAdapter和网格视图的相同,不过新增了几个设置,setLayoutParams可以设置imageView的宽高,typeArray可以指定它的样式,需要在values里新建attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
    <declare-styleable name="Gallery">
        <attr name="android:galleryItemBackground"/>
    </declare-styleable>
</resources>

另外,gallery不要忘记了配置适配器和选中的图片,这里选择的中间的图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02imI1p2-1637733437896)(C:\Users\Michilay\AppData\Roaming\Typora\typora-user-images\image-20211123213214884.png)]

画廊视图可以和图像切换器结合做成幻灯片选择播放

还是得通过imageSwitcher.setFactory的方法初始化is,通过gallery.setAdapter(baseAdapter);的方式初始化gallery

最后设置

gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        imageSwitcher.setImageResource(image[position]);
    }
});

效果如下

在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-25 08:13:48  更:2021-11-25 08:16:33 
 
开发: 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年11日历 -2024/11/24 5:00:26-

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