文章目录

  • **`TestView`**
  • **`Toast`**
  • **`CheckBox`**
  • **`RadioGroup&RadioButton`**
  • **`Button`**
  • **`EditText`**
  • **`ImageView`**
  • **`进度条`**
  • **`ProgressBar`**
  • **`SeekBar`**
  • **`RatingBar`**
  • **`AlertDialog`**
  • **`ProgressDialog`**
  • **`时间日期控件`**
  • **`TimePicker`**
  • **`DatePicker`**
  • **`ListView`**
  • **`RecyclerView`**
  • **`WebView`**
  • ScrollView—让你的布局滚动起来


TestView

它主要用于在界面上显示一段文本信息

<TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textSize="24sp"
        android:textColor="#00ff00"
        android:text="This is TextView"/>

android:id 给当前控件定义一个唯一标识符

android:layout_widthandroid:layout_height指定控件的宽度和高度。Android所有的空间都有这两个属性,可选值三种,
match_parent表示让当前控件的大小和父布局大小一样。也就是由父布局决定控件的大小
fill_parent 和 match_parent相似
wrap_content 表示让当前空间的大小能够刚好包含住里面的内容。也就是与控件的内容决定控件的大小

android:text指定TextView中显示的文本

android:gravity 来指定文字的对齐方式,可选值有top,bottom,left,right,center等,可以用 | 来同时指定多个值,这里我们指定的center,效果等同于center_vertical|center_horizontal,表示文字在垂直和水平方向都居中对齐。

android:textSize 属性可以指定文字的大小

android:textColor属性可以指定文字的颜色

Toast

Toast 是Android 系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,这些信息在一段时间后会自动消失,并且不会占用任何屏幕空间。

该方法的一般用法:
Toast toast = Toast.makeText(context, “”, time);
这三个参数分别是:
1.当前的上下文环境;(getApplicationContext这个方法可以获取)
2.要显示的字符串;(就是一般的字符串,可以写在string.xml中)
3.显示的时间长短;(有toast默认的参数,也可以自己设定)

Toast.makeText(FirstActivity.this,"i learn english",
                        Toast.LENGTH_SHORT).show();
CheckBox

多选框,一个CheckBox对应一个框。
注册点击事件监听器

public class MainActivity extends AppCompatActivity {
    private CheckBox eatBox;
    private CheckBox sleepBox;
    private CheckBox playBox;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        eatBox = (CheckBox) findViewById(R.id.eatBox);
        sleepBox = (CheckBox) findViewById(R.id.sleepBox);
        playBox = (CheckBox)  findViewById(R.id.playBox);

        OnBoxClickListener listener = new OnBoxClickListener();
        eatBox.setOnClickListener(listener);
        sleepBox.setOnClickListener(listener);
        playBox.setOnClickListener(listener);

    }
    class OnBoxClickListener implements View.OnClickListener{

        @Override
        public void onClick(View view) {
            CheckBox box = (CheckBox) view;
            String Msg = "";
            if(box.getId() == R.id.eatBox) Msg = "eatBox";
            else if(box.getId() == R.id.sleepBox) Msg = "sleepBox";
            else if(box.getId() == R.id.playBox) Msg = "playBox";

            if(box.isChecked()) Msg += " checked!";
            else Msg += " unchecked!";
            Toast.makeText(MainActivity.this,Msg,Toast.LENGTH_SHORT).show();
        }
    }
}

注册状态改变事件监听器

public class MainActivity extends AppCompatActivity {
    private CheckBox eatBox;
    private CheckBox sleepBox;
    private CheckBox playBox;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        eatBox = (CheckBox) findViewById(R.id.eatBox);
        sleepBox = (CheckBox) findViewById(R.id.sleepBox);
        playBox = (CheckBox)  findViewById(R.id.playBox);

        CheckBoxListener listener = new CheckBoxListener();
        eatBox.setOnCheckedChangeListener(listener);
        sleepBox.setOnCheckedChangeListener(listener);
        playBox.setOnCheckedChangeListener(listener);

    }
    class CheckBoxListener implements CompoundButton.OnCheckedChangeListener {


        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            String Msg = "";
            if(compoundButton.getId() == R.id.playBox)
                if(b) Msg = "playBox checked!";
                else Msg = "PlayBox unchecked!";
            else if(compoundButton.getId() == R.id.sleepBox)
                if(b) Msg = "sleepBox checked!";
                else Msg = "sleepBox unchecked!";
            else if(compoundButton.getId() == R.id.eatBox)
                if(b) Msg = "eatBox checked!";
                else Msg = "eatBox unchecked!";

            Toast.makeText(MainActivity.this,Msg,Toast.LENGTH_SHORT).show();
        }
    }
}

isChecked() 判断当前框是否被选中
setCheckted(boolean)设置当前框的状态

RadioGroup&RadioButton

单选按钮在逻辑上是成组出现的,即一组中只能选择一个按钮。
RadioButton 是 RadioGroup的字标签,xml文档中如下表示

<RadioGroup
        android:id="@+id/group1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="男性"/>

        <RadioButton
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="女性"/>

    </RadioGroup>

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_ide

注册OnCheckedChangeListener监听器的方式有两种,一个是为每一个按钮注册监听器,一个是为每一组注册一个监听器。

注意:两个监听器虽然名字都是·OnCheckedChangeListener·,但在不同包下,为按钮注册的监听器和多选按钮注册的包名一样 ,是CompoundButton;而为组对象注册的监听器包是RadioGroup。

下面是选择为组对象注册监听器

public class MainActivity extends AppCompatActivity {
    private RadioGroup radioGroup;
    private RadioButton radioButton1;
    private RadioButton radioButton2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        radioGroup = (RadioGroup) findViewById(R.id.group1);
        radioButton1 = (RadioButton) findViewById(R.id.button1);
        radioButton2 = (RadioButton) findViewById(R.id.button2);

        RadioGroupListener listener = new RadioGroupListener();
        radioGroup.setOnCheckedChangeListener(listener);
    }

    class RadioGroupListener implements RadioGroup.OnCheckedChangeListener{

        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int i) {
            String Msg = "";
            if(i == radioButton1.getId()) Msg = "male checked!";
            else if(i == radioButton2.getId()) Msg = "female checked!";
            Toast.makeText(MainActivity.this, Msg, Toast.LENGTH_SHORT).show();
        }
    }
}
Button

注意系统会默认将Button的所有英文字符自动进行大写转换,我们要通过android:textAllCaps属性来禁用它。

<Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAllCaps="false"
        android:text="Button"/>

然后我们在活动类中为Button的点击事件注册一个监听器
匿名类的方式来注册监听器

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                //再此处添加逻辑
            }
        });
    }
}

如果不喜欢这种匿名类的方式来注册监听器,也可以使用实现接口的方式来进行注册。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                //在此处添加逻辑
                break;
            default:
                break;
        }
    }
}

内部类实现注册监听器

public class MainActivity extends AppCompatActivity {
    private CheckBox eatBox;
    private CheckBox sleepBox;
    private CheckBox playBox;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        eatBox = (CheckBox) findViewById(R.id.eatBox);
        sleepBox = (CheckBox) findViewById(R.id.sleepBox);
        playBox = (CheckBox)  findViewById(R.id.playBox);

        OnBoxClickListener listener = new OnBoxClickListener();
        eatBox.setOnClickListener(listener);
        sleepBox.setOnClickListener(listener);
        playBox.setOnClickListener(listener);

    }
    class OnBoxClickListener implements View.OnClickListener{

        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this,"hello",Toast.LENGTH_SHORT).show();
        }
    }
EditText

android:hint 属性让我们可以添加提示文字

android:maxLines 指定EditText的最大行数。当输入的文字超过指定的行数时,文本就会向上滚动,而EditText则不会在继续延伸

实例:Button 与 EditText结合

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.edit_text);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                String inputText = editText.getText().toString();
                Toast.makeText(MainActivity.this,inputText,
                        Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
    }
}
ImageView

ImageView是用于在界面上展示图片的一个控件,它可以让我们的程序世界变得更加丰富多彩。
图片通常都是放在以’drawable’开头的目录下的,并且指定分辨率。

android:src 属性给Image_View指定一张图片。
android:scaleType 属性 不匹配情况下拉伸图片

<ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/img_1"/>

按钮事件来显示指定的图片

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editText;
    private ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.edit_text);
        imageView = (ImageView) findViewById(R.id.image_view);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                imageView.setImageResource(R.drawable.img_2);
                break;
            default:
                break;
        }
    }
}
进度条
ProgressBar

ProgressBar 用于在界面上显示一个进度条,表示我们的程序正在加载一些数据。

<ProgressBar
        android:id="@+id/progesss_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"
        android:max="100"/>

style属性设置ProgressBar样式

android:max 属性给进度条设置一个最大值
android:progress 属性 设置进度条当前进度值

怎么让进度条消失,所以android 控件都有这个属性,android:visibility,可选值有三种
visible 表示控件是课件的,默认值
invisible 表示控件不可见,但是仍然占据空间
gone表示控件不可见,也不占据空间
我们还可以通过代码设置控件的可见性,使用的是setVisibility()方法,可以传入View.VISIBLE,View.INVISIBLEView.GONE这3种值。

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_ide_02

通过点击按钮来增加进度值。

package com.example.uiwidgettest;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editText;
    private ImageView imageView;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.edit_text);
        progressBar = (ProgressBar) findViewById(R.id.progesss_bar);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                int progress = progressBar.getProgress();
                progress = progress + 10;
                progressBar.setProgress(progress);
                break;
            default:
                break;
        }
    }
}
SeekBar

可拖动的进度条。

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_03

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_04

public class MainActivity extends AppCompatActivity {
    private SeekBar seekBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        seekBar = (SeekBar) findViewById(R.id.s1);

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            /**
             *
             * @param seekBar 触发了监听器的SeekBar对象
             * @param progress 当前SeekBar对象的进度
             * @param fromuser 是不是用户拖动导致进度条发生改变
             */
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromuser) {
                Toast.makeText(MainActivity.this,progress +" " +fromuser,
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Toast.makeText(MainActivity.this,"Star",
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Toast.makeText(MainActivity.this,"End",
                        Toast.LENGTH_SHORT).show();
            }
        });


    }
}
RatingBar

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_05

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_06

public class MainActivity extends AppCompatActivity {
    private RatingBar ratingBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ratingBar = (RatingBar) findViewById(R.id.r1);

        ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUsre) {
                Log.d("My","rating: " + rating +" fromUser: " + fromUsre);
            }
        });
    }
}
AlertDialog

AlertDialog 可以在当前的界面弹出一个对话框,这个对话框是置顶于所有界面元素之上的,能够屏蔽其他控件的交互能力,因此AlertDialog 一般都是用于提示一些非常重要的内容或者警告信息。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editText;
    private ImageView imageView;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.edit_text);
        progressBar = (ProgressBar) findViewById(R.id.progesss_bar);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                AlertDialog.Builder dialog= new AlertDialog.Builder(MainActivity.this);
                dialog.setTitle("This is Dialog");
                dialog.setMessage("Something important.");
                dialog.setCancelable(false);
                dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //设置确定按钮的点击
                    }
                });
                dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //设置取消按钮的点击事件
                    }
                });
                AlertDialog dialog_entry = dialog.create();
        		dialog_entry.show();//显示对话框
        		dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.parseColor("#fd8d99"));//给按钮换颜色

                break;
            default:
                break;
        }
    }
}

首先通过AlertDialog.Builder创建一个AlertDialog的实例,然后可以为这个对话框设置标题、内容,可否取消等属性,接下来调用setPositiveButton()方法为对话框确定按钮的点击事件,调用setNegativeButton()方法设置取消按钮的点击事件,最后调用show()方法将对话框显示出来。

ProgressDialog

和 AlertDialog比较类似,不同的是,ProgressDialog会在对话框中显示一个进度条,一般用于表示当前操作比较耗时,让用户耐心等待。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editText;
    private ImageView imageView;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.button);
        editText = (EditText) findViewById(R.id.edit_text);
        progressBar = (ProgressBar) findViewById(R.id.progesss_bar);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                ProgressDialog progressdialog= new ProgressDialog (MainActivity.this);
                progressdialog.setTitle("This is ProgressDialog");
                progressdialog.setMessage("Loading...");
                progressdialog.setCancelable(true);
                progressdialog.show();//显示对话框
                break;
            default:
                break;
        }
    }
}

注意,如果在setCancelable()中传入了false,表示ProgressDialog是不能通过Back键取消掉的,这是你就一定要在代码中做好控制,当数据加载完成后必须要调用ProgressDialog的dismiss()方法来关闭对话框,否则ProgressDialog将会一直存在

时间日期控件
TimePicker

时间控件

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_07


注册OnTimeChangedListener监听器(匿名类方式)

public class MainActivity extends AppCompatActivity {
    private TimePicker timePicker;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        timePicker = (TimePicker) findViewById(R.id.p1);
        timePicker.setIs24HourView(true);
        timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            @Override
            public void onTimeChanged(TimePicker timePicker, int i, int i1) {
                Toast.makeText(MainActivity.this,"Hour: "+i + " Minute: " + i1,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
}
DatePicker

日期控件

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_ide_08

ListView

当我们的程序有大量的数据需要展示的时候,就可以借助ListView来实现,它允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚出屏幕。

常用属性
分割线属性divider
Item按下颜色listSelector
右侧快速滑动标签fastScroll
去除ListView滑到顶部和底部时边缘的黑色阴影
按下阴影显示Item之上drawSelectorOnTop
具体请访问链接

一个简单的用法
activity_main.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">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private String[] data = {"Apple","Banana","Orage","Watermelon",
            "Pear","Grape","Pineapple","Strawberry","Cherry","Mango",
            "Apple","Banana","Orage","Watermelon","Pear","Grape","Pineapple",
            "Strawberry","Cherry","Mango"};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("水果篮");
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                MainActivity.this,android.R.layout.simple_list_item_1,data
        );
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
    }
}

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_09


这里我们简单用一个data数组测试,里面包含很多水果名称

不过,数组中的数据是无法直接传递给ListView的,我们还需要借助适配器来完成。Android中提供很多适配器的实现类,其中我认为最好用的就是ArrayAdapter,他可以借助泛型来指定要是适配的数据类型,然后在构造函数中把要适配的数据传入。
ArrayAdapter 有多个构造函数的重载,你应该根据实际情况选择最合适的一种。

定制ListView的界面

效果如下

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_10


我们定义一个实体类Fruit类,作为ListView适配器的适配类型。

public class Fruit {
    private String name;//水果名称
    private int imageId;//水果图片
    private String text;//水果描述

    public Fruit(String name,int imageId,String text){
        this.name = name;
        this.imageId = imageId;
        this.text = text;
    }
    public String getName(){
        return name;
    }
    public int getImageId(){
        return imageId;
    }
    public String getText(){
        return text;
    }
}

然后为ListView的子项指定一个自定义的布局fruit_item.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">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <TextView
            android:id="@+id/fruit_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
        />
        <TextView
            android:id="@+id/fruitText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="bottom"
            android:layout_marginTop="10dp"/>
    </LinearLayout>

</LinearLayout>

然后创建一个自定义的适配器类FruitAdapter,这个适配器继承自ArrayAdapter,并 将泛型指定为Fruit.

public class FruitAdapter extends ArrayAdapter<Fruit> {
    private int resourceId;
    public FruitAdapter(@NonNull Context context, int resource,
                        @NonNull List<Fruit> objects) {
        super(context, resource, objects);
        resourceId = resource;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        Fruit fruit = getItem(position);//获取当前Fruit实例
        View view;
        ViewHolder viewHolder;
        if(convertView == null){
            view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
            viewHolder = new ViewHolder();
            viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
            viewHolder.fruitText =  (TextView) view.findViewById(R.id.fruitText);
            view.setTag(viewHolder);//将ViewHolder存储在View中
        }
        else{
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();//重新获取ViewHolder
        }
        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.fruitName.setText(fruit.getName());
        viewHolder.fruitText.setText(fruit.getText());
        return view;
    }
    class ViewHolder{
        ImageView fruitImage;
        TextView fruitName;
        TextView fruitText;
    }
}

FruitAdapter重写了父类的一组构造方法,用于将上下文,ListView子项布局的id和数据都传进来。然后重写了getView方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。
getView()方法中有个convertView参数,这个参数用于将之前加载好的布局进行缓存,以便重用,这样就不会每次都重新加载布局了。然后我们新建类ViewHolder用来解决每次都调用findViewById()来获取控件实例的问题。

接下来我们修改MainActivity.java代码

public class MainActivity extends AppCompatActivity {

   private List<Fruit> fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();//初始化水果数据
        FruitAdapter adapter = new FruitAdapter(MainActivity.this,
                R.layout.fruit_item,fruitList);
        ListView listView = (ListView) findViewById(R.id.lv1);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new ListView.OnItemClickListener(){
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Fruit fruit  = fruitList.get(i);
                Toast.makeText(MainActivity.this,fruit.getName(),
                            Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initFruits() {
        for(int i = 0;i < 2;++ i){
            Fruit apple = new Fruit("Apple",R.drawable.apple_pic,"This is an apple.");
            fruitList.add(apple);
            Fruit banana = new Fruit("Banana",R.drawable.banana_pic,"This is a banana.");
            fruitList.add(banana);
            Fruit orange = new Fruit("Orange",R.drawable.orange_pic,"This is an orange.");
            fruitList.add(orange);
            Fruit pear = new Fruit("Pear",R.drawable.pear_pic,"This is a pear.");
            fruitList.add(pear);
        }
    }
}

我们在onCreate()方法中创建FruitAdapter对象,并将FruitAdapter作为适配器传给ListView。这样页面就完成了。
最后我们使用setOnItemClickListener()方法为ListView注册一个监听器,当用户点击ListView中的任何一个子项时,就会回调onItemClick()方法。

RecyclerView

更强大的滚动控件,可以说是增强版的ListView,不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足。

因为RecyclerView属于新增的控件,Android将RecyclerView定义在support库里。若要使用RecyclerView,第一步是要在build.gradle中添加对应的依赖库。

添加RecyclerView 依赖库
app/build.gradle中的dependencies闭包添加以下内容:

implementation 'com.android.support:recyclerview-v7:27.1.1'

然后点击顶部的Sync Now进行同步

在activity_main.xml添加如下内容使用

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

这里我们简单实现如下界面

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_11


这和上面ListView实现的界面差不多。

照样写一个Fruit实体类,然后写一个子项布局fruit_item.xml

public class Fruit {
    private String name;
    private int imageId;

    public Fruit(String name, int imageId){
        this.name = name;
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }
}
<?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="wrap_content">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"/>

</LinearLayout>

然后为RecyclerView准备一个适配器FruitAdapter类,让这个类继承RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,其中ViewHolder是我们在FruitAdapter中定义的一个内部类。

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{

    private List<Fruit> mFruitList;

    static  class ViewHolder extends  RecyclerView.ViewHolder{
        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            fruitImage = (ImageView) itemView.findViewById(R.id.fruit_image);
            fruitName = (TextView) itemView.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruitList){
        mFruitList = fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//创建ViewHolder实例,并将fruit_item布局加载进来
        View view = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.fruit_item,parent,false
        );
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {//对子项数据赋值
        Fruit fruit = mFruitList.get(position);
        holder.fruitImage.setImageResource(fruit.getImageId());
        holder.fruitName.setText(fruit.getName());
    }

    @Override
    public int getItemCount() {//返回子项的数目
        return mFruitList.size();
    }

}

最后我们修改MainActivity.java的代码。

public class MainActivity extends AppCompatActivity {

    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();//初始化水果数据
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);//LayoutManger用于指定RecyclerView的布局方式,这里LinearLayoutManger是线性布局的意思
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i = 0;i < 2; i ++){
            Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit banana = new Fruit("banana",R.drawable.banana_pic);
            fruitList.add(banana);
            Fruit orange = new Fruit("banana",R.drawable.orange_pic);
            fruitList.add(orange);
            Fruit watermelon = new Fruit("watermelon",R.drawable.watermelon_pic);
            fruitList.add(watermelon);
        }
    }
}

实现横向滚动和瀑布流布局

实现横向滚动,还是对上面的代码进行操作,效果如下。

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_12


我们要对子项布局fruit_item.xml进行布局上的些许修改,因为目前这个布局的元素是水平排列的,适合纵向滚动,我们要把子项布局中元素改为纵向排列才比较合理。

fruit_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>

</LinearLayout>

然后修改MainActivity.java的代码

public class MainActivity extends AppCompatActivity {

    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//设置布局的排列方向,默认纵向布局
        recyclerView.setLayoutManager(layoutManager);
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i = 0;i < 2; i ++){
            Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit banana = new Fruit("banana",R.drawable.banana_pic);
            fruitList.add(banana);
            Fruit orange = new Fruit("banana",R.drawable.orange_pic);
            fruitList.add(orange);
            Fruit watermelon = new Fruit("watermelon",R.drawable.watermelon_pic);
            fruitList.add(watermelon);
        }
    }
}

除了LinearManger之外,RecyclerView还给我们提供了GirdLayoutManger和StaggeredGirLayoutManger两种内置的布局方式,GirdLayoutManger可以用来实现网格布局,StaggeredGirLayoutManger可以用于实现瀑布流布局。

下面我们先实现下瀑布流布局。

效果如下

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_android_13


还是先修改下子项布局fruit_item.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="wrap_content"
    android:layout_margin="5dp">

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:layout_marginTop="10dp"/>

</LinearLayout>

然后修改MainActivity.java

public class MainActivity extends AppCompatActivity {

    private List<Fruit> fruitList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        StaggeredGridLayoutManager layoutManager = new
                StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);//第一个参数是布局列数,第二个参数是布局的排列方向
        FruitAdapter adapter = new FruitAdapter(fruitList);
        recyclerView.setAdapter(adapter);
    }
    private void initFruits(){
        for(int i = 0;i < 2; i ++){
            Fruit apple = new Fruit(getRandomLengthName("Apple"),R.drawable.apple_pic);
            fruitList.add(apple);
            Fruit banana = new Fruit(getRandomLengthName("banana"),R.drawable.banana_pic);
            fruitList.add(banana);
            Fruit orange = new Fruit(getRandomLengthName("banana"),R.drawable.orange_pic);
            fruitList.add(orange);
            Fruit watermelon = new Fruit(getRandomLengthName("watermelon"),R.drawable.watermelon_pic);
            fruitList.add(watermelon);
        }
    }
    private String getRandomLengthName(String name){//随机生成1-20之间的数,将字符串重复几遍,更好的显示布局效果
        Random random = new Random();
        int length = random.nextInt(20) + 1;
        StringBuilder builder = new StringBuilder();
        for(int i = 0;i < length;++ i){
            builder.append(name);
        }
        return builder.toString();
    }
}

RecyclerView的点击事件
它并没有提供现有的监听器供我们使用,而是需要我们自己给子项具体的View去注册事件。

我们修改FruitAdapter.java中的代码

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{

    private List<Fruit> mFruitList;

    static  class ViewHolder extends  RecyclerView.ViewHolder{
        View fruitView;
        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            fruitView = itemView;
            fruitImage = (ImageView) itemView.findViewById(R.id.fruit_image);
            fruitName = (TextView) itemView.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter(List<Fruit> fruitList){
        mFruitList = fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.fruit_item,parent,false
        );
        final ViewHolder holder = new ViewHolder(view);
        holder.fruitView.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText(view.getContext(),"you clicked view " + fruit.getName(),
                        Toast.LENGTH_SHORT).show();
            }
        });
        holder.fruitImage.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText(view.getContext(),"you clicked image " + fruit.getName(),
                        Toast.LENGTH_SHORT).show();
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitImage.setImageResource(fruit.getImageId());
        holder.fruitName.setText(fruit.getName());
    }

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

}

我们先是在ViewHolder中添加fruitView来保存子项最外层的布局实例,然后注册点击事件,这里将最外层的布局和ImageView都注册了点击事件。在点击事件中,先是获取用户点击的positon,然后通过position获取Fruit实例,在用Toast弹出信息。

WebView

借助它我们可以在自己的应用程序里嵌套一个浏览器,从而非常轻松的来展示各种各样的网页。
例子,在应用内打开百度。新建一个WebViewTest项目
修改activity_main.xml代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

然后修改MainActivity代码
借助getSettings()方法可以去设置一些浏览器的属性,这里我们并不去设置过多属性,只是调用setJavaScriptEnabled()方法来让WebView支持JavaScript脚本
然后调用WebView的setWebViewClient()方法,并传入一个WebViewClient实例,这段代码的作用是,当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前WebView中显示,而不是打开系统浏览器。最后就是调用WebView的loadUrl()方法并将网址传入,即可展示相应的内容。
另外本程序使用到了网络功能,而访问网络是需要声明权限的,因此我们还得修改AndroidManifest.xml文件,并加入权限声明,并且android10.0对未加密的流量不信任,需要再加入新的限制,我么需要在<aplication 标签内 设置usesCleartextTraffic 属性为true

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.webview">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这样就可以访问百度了。

ScrollView—让你的布局滚动起来

简介
ScrollView称为滚动视图,当在一个屏幕的像素显示不下绘制的UI控件时,可以采用滑动的方式,使控件显示。

先看下ScrollView类的继承关系:

java.lang.Object
  ↳android.view.View
    ↳android.view.ViewGroup
      ↳android.widget.FrameLayout
        ↳android.widget.ScrollViewz

可以看出,ScrollView原来是一个FrameLayout的容器,不过在他的基础上添加了滚动,允许显示的比实际多的内容。
使用方式
1.竖直滚动视图ScrollView
在页面的竖直方向线性布局5个Button,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="内容一"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:text="内容二"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:text="内容三"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:text="内容四"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:layout_marginBottom="80dp"
            android:gravity="center"
            android:text="内容五"
            android:textColor="#03A9F4"
            android:textSize="24sp" />
    </LinearLayout>
</ScrollView>

通过Android Studio的Preview视图也可以看出,5个Button已超出屏幕显示,在不使用ScrollView的情况下,父布局直接使用LinearLayout,是无法使屏幕滑动显示所有控件的。

使用ScrollView后显示如下:

第一行代码android第二版pdf彩色 第一行安卓代码第二版pdf_Group_14


注意:ScrollView的子元素只能有一个,可以是一个View(如ImageView、TextView等) 也可以是一个ViewGroup(如LinearLayout、RelativeLayout等),其子元素内部则不再限制,否则会报以下异常。

Caused by: java.lang.IllegalStateException: ScrollView can host only one direct child

2.水平滚动视图HorizontalScrollView
在实际使用时,我们也会遇到水平方向,控件超出屏幕的情况。这时就需要使用水平方向的滚动视图HorizontalScrollView。

在上面代码头部新增一个HorizontalScrollView,水平方向线性布局4个ImageView,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="20dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <ImageView
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:layout_margin="20dp"
                    android:src="@mipmap/ic_launcher" />

                <ImageView
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:layout_margin="20dp"
                    android:src="@mipmap/ic_launcher" />

                <ImageView
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:layout_margin="20dp"
                    android:src="@mipmap/ic_launcher" />

                <ImageView
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:layout_margin="20dp"
                    android:src="@mipmap/ic_launcher" />

            </LinearLayout>
        </HorizontalScrollView>

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="20dp"
            android:gravity="center"
            android:text="内容一"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:text="内容二"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:gravity="center"
            android:text="内容三"
            android:textColor="#03A9F4"
            android:textSize="24sp" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="80dp"
            android:layout_marginBottom="80dp"
            android:gravity="center"
            android:text="内容四"
            android:textColor="#03A9F4"
            android:textSize="24sp" />
    </LinearLayout>
</ScrollView>

可以看出,HorizontalScrollView中的图片内容,可以横向滑动,并且整个布局由于外部嵌套了ScrollView,整体页可以竖直方向滑动。

注意:同ScrollView,HorizontalScrollView中的子元素也只能有一个,否则报错。

XML中常用属性介绍
1.android:fadingEdge=“none”

设置拉滚动条时,边框渐变的方向。none(边框颜色不变),horizontal(水平方向颜色变淡),vertical(垂直方向颜色变淡)。

2.android:overScrollMode=“never”

删除ScrollView拉到尽头(顶部、底部),然后继续拉出现的阴影效果,适用于2.3及以上的 否则不用设置。

3.android:scrollbars=“none”

设置滚动条显示,none(隐藏),horizontal(水平),vertical(垂直)。

4.android:descendantFocusability=""

该属性是当一个为view获取焦点时,定义ViewGroup和其子控件两者之间的关系。
属性的值有三种:

beforeDescendants	//viewgroup会优先其子类控件而获取到焦点
afterDescendants	//viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants	//viewgroup会覆盖子类控件而直接获得焦点

5.android:fillViewport=“true"

这是 ScrollView 独有的属性,用来定义 ScrollView 对象是否需要拉伸自身内容来填充
viewport。通俗来说,就是允许ScrollView去填充整个屏幕。比如ScrollView嵌套的子控件高度达不到屏幕高度时,虽然ScrollView高度设置了match_parent,也无法充满整个屏幕,需设置android:fillViewport=“true"使ScrollView填充整个页面,给ScrollView设置背景颜色就能体现。
常用方法:
滑动开关控制

scrollView.setOnTouchListener(new View.OnTouchListener() {
	@Override
 	public boolean onTouch(View view, MotionEvent motionEvent) {
        // true禁止滑动  false可滑动
 		return true;
  	}
});

滑动位置控制

scrollView.post(new Runnable() {
	@Override
	public void run() {
		//滑动到顶部
		scrollView.fullScroll(ScrollView.FOCUS_UP);
        
        //滑动到底部
        scrollView.fullScroll(ScrollView.FOCUS_DOWN);
	}
});

滑动到某个位置

scrollView.post(new Runnable() {
	@Override
	public void run() {
		//偏移值
		int offset = 100;
		scrollView.smoothScrollTo(0, offset);
	}
});

结语
可以看出,ScrollView是在日常开发中经常使用的View控件,其使用方式也比较简单。