ViewPager
什么是ViewPager?
- ① 翻页类视图,水平方向,上翻页进行数据展示
- ② 具体参照如图:
如何使用ViewPager
- 搭建ViewPager布局
- 准备数据和单条数据视图
- 创建Adapter并初始化ViewPager
- 展示
ViewPager的缓冲原理
- 为什么要进行缓冲
- 缓冲原理同ListView
- 优化适配器实现ListView缓冲
- 使用缓存
- 优化控件的获取
ViewPager的常用函数
- getCount
- isViewFromObject
- destroyItem
- instantiateItem
PageTitleStrip
什么是PageTitleStrip?
- 给页面加载的标题
实现步骤
- 准备数据
- 添加布局
- 实现getPageTitle方法
PageTabStrip
什么是PageTabStrip?
- 给页面加载可以点击的标题
实现步骤
- 准备数据
- 添加布局
- 实现getPageTitle方法
实现启动页引导页
实现步骤
- 准备数据
- 添加布局
- 自定义视图
- 完成适配器
- 展示
数据存储
为什么要使用数据存储?
- 存储一些必要的信息
- 存储数据, 降低访问量
- 存储数据,提升用户体验
数据存储的方式
- SharePreferences
- SQLite
- SD卡文件操作
- ContentProvider
SharePreferences
存储特点
- ① 简单且孤立的数据
- ② 文本形式的 数据
- ③ 可以存储持久化的数据
- ④ 存储数据的方式使用key-value形式
使用SharePreferences
- ① 存储位置: /data/data/应用包名/shared prefs/文件名. xml
- ② 插入数据: Editor
- ③ 获取数据
实现记住密码功能
SQLite
嵌入式数据库
- 可以存储复杂的关系数据
- 使用方式同数据库
- 可以存储持久化的数据
重要的类
- SQLiteDatabase:数据库/链接
- SQLiteOpenHelper
- Cursor
- ContentValues
使用SQLite
- 定义SQLiteOpenHelper
- 获取链接
- 定义SQL语句
- 执行SQL语句
实现增删改查
- 增加:insert
- 删除:delete
- 修改:update
- 查询:query
代码部分:
part1:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示ViewPager"
android:textAllCaps="false"
android:onClick="showViewPagerDemo"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示简单使用ViewPager"
android:textAllCaps="false"
android:onClick="showSimpleDemo"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示引导页"
android:onClick="showGuidance"/>
</LinearLayout>
效果图:
activity_view_pager_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--<androidx.viewpager.widget.PagerTitleStrip
android:id="@+id/pageTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>-->
<androidx.viewpager.widget.PagerTabStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.viewpager.widget.ViewPager>
</RelativeLayout>
效果图:
Demo.java
/**
* 封装ViewPager数据
*/
public class Demo {
//标题
private String title;
//图片
private int image;
public Demo(String title, int image) {
this.title = title;
this.image = image;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
}
pager_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/picture1"/>
</RelativeLayout>
效果图:
picture1.png
picture2.png
picture3.png
picture4.png
MyViewPagerAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class MyViewPagerAdapter extends PagerAdapter {
//数据
private List<View> data;
//上下文,用于将xml转换成View类
private Context context;
/**
* 构造方法
* @param demoData
* @param context
*/
public MyViewPagerAdapter(List<Demo> demoData, Context context) {
//上下文
this.context = context;
this.data = new ArrayList<>();
LayoutInflater inflater = LayoutInflater.from(context);
//转化数据
for (int i = 0; i < demoData.size(); i++) {
View view = inflater.inflate(R.layout.pager_item, null);
ImageView imageView = view.findViewById(R.id.iv_image);
imageView.setImageResource(demoData.get(i).getImage());
this.data.add(view);
}
}
/**
* 获取视图
* @param container ViewPager
* @param position 视图位置
* @return
*/
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//1.添加视图到ViewPager
container.addView(data.get(position));
//2.返回视图
return data.get(position);
}
/**
* 销毁视图
* @param container
* @param position
* @param object
*/
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(data.get(position)); // 移除视图
}
/**
* 获取条数
* @return
*/
@Override
public int getCount() {
return data.size();
}
/**
* 判断View是否是与key相等
* @param view
* @param object
* @return
*/
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
/**
* 获取标题
* @param position
* @return
*/
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return "我是测试用的";
}
}
ViewPagerDemoActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerDemoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager_demo);
//数据
List<Demo> data = new ArrayList<>();
Demo demo = new Demo("第一页", R.drawable.picture1);
data.add(demo);
Demo demo1 = new Demo("第二页", R.drawable.picture2);
data.add(demo1);
Demo demo2 = new Demo("第三页", R.drawable.picture3);
data.add(demo2);
Demo demo3 = new Demo("第四页", R.drawable.picture4);
data.add(demo3);
//初始化ViewPager
ViewPager viewPager = findViewById(R.id.vp_viewPager);
MyViewPagerAdapter adapter = new MyViewPagerAdapter(data, this);
viewPager.setAdapter(adapter);
}
}
效果图:
part2:
activity_simple_view_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.viewpager.widget.ViewPager
android:id="@+id/vp_simple"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
效果图:
SimpleViewPagerActivity.java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;
public class SimpleViewPagerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_view_pager);
//准备数据、创建item视图
final List<View> data = new ArrayList<>();
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.picture1); //添加ImageView的布局
data.add(imageView);
ImageView imageView1 = new ImageView(this);
imageView1.setImageResource(R.drawable.picture2); //添加ImageView的布局
data.add(imageView1);
ImageView imageView2 = new ImageView(this);
imageView2.setImageResource(R.drawable.picture3); //添加ImageView的布局
data.add(imageView2);
ImageView imageView3 = new ImageView(this);
imageView3.setImageResource(R.drawable.picture4); //添加ImageView的布局
data.add(imageView3);
// for (int i = 0; i < 4; i++) {
// ImageView image = new ImageView(this);
// Context context = getBaseContext();
// int id = context.getResources().getIdentifier("picture4", "drawable", context.getPackageName());
// image.setImageResource(id);
// data.add(image);
// }
//初始化ViewPager
ViewPager viewPager = findViewById(R.id.vp_simple);
viewPager.setAdapter(new PagerAdapter() {
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
container.addView(data.get(position));
return data.get(position);
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView(data.get(position));
}
@Override
public int getCount() {
return data.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
});
}
}
效果图:
part3:
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 用于演示ViewPager
* @param view
*/
public void showViewPagerDemo(View view) {
Intent intent = new Intent(this, ViewPagerDemoActivity.class);
startActivity(intent);
}
/**
* 用于演示简单使用ViewPager
* @param view
*/
public void showSimpleDemo(View view){
Intent intent = new Intent(this, SimpleViewPagerActivity.class);
startActivity(intent);
}
/**
* 用于演示引导页
* @param view
*/
public void showGuidance(View view) {
Intent intent = new Intent(this, GuidanceDemoActivity.class);
startActivity(intent);
}
}
activity_guidance_demo.xml
?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.viewpager.widget.ViewPager
android:id="@+id/guidanceViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
效果图:
guidance_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/picture2"/>
<RadioGroup
android:id="@+id/rg_radioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp">
</RadioGroup>
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="立即体验"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:visibility="gone"/>
</RelativeLayout>
效果图:
GuidanceAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;
import java.util.List;
public class GuidanceAdapter extends PagerAdapter {
// 数据
private List<Integer> data;
//上下文
private Context context;
//LayoutInflater
private LayoutInflater inflater;
/**
* 构造方法
* @param data
* @param context
*/
public GuidanceAdapter(List<Integer> data, Context context) {
this.data = data;
this.context = context;
this.inflater = LayoutInflater.from(context);
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
// 1.添加视图到容器
View view = inflater.inflate(R.layout.guidance_item, null);
ImageView imageView = view.findViewById(R.id.iv_image);
RadioGroup radioGroup = view.findViewById(R.id.rg_radioGroup);
Button startButton = view.findViewById(R.id.startButton);
// 给ImageView赋值
imageView.setImageResource(data.get(position));
// 显示按钮、隐藏RadioGroup和给按钮添加事件
if (position == (data.size()-1)) {
radioGroup.setVisibility(View.GONE);
startButton.setVisibility(View.VISIBLE);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, "欢迎使用" , Toast.LENGTH_SHORT).show();
}
});
}
// 循环产生Radio,并选中指定的Radio
for(int i=0; i<data.size(); i++){
RadioButton radioButton = new RadioButton(context);
if (i == position) {
radioButton.setChecked(true);
}
radioGroup.addView(radioButton);
}
container.addView(view);
// 2.返回视图
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
// 销毁视图
container.removeView((View) object);
}
@Override
public int getCount() {
return data.size();
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
}
GuidanceDemoActivity.java
import java.util.ArrayList;
import java.util.List;
public class GuidanceDemoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guidance_demo);
// 数据
List<Integer> data = new ArrayList<>();
data.add(R.drawable.picture1);
data.add(R.drawable.picture2);
data.add(R.drawable.picture3);
data.add(R.drawable.picture4);
// 初始化ViewPager
ViewPager viewPager = findViewById(R.id.guidanceViewPager);
GuidanceAdapter adapter = new GuidanceAdapter(data, this);
viewPager.setAdapter(adapter);
}
}
效果图:
前三页
最后一页
part4:
另建新的工程
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示SharePreferences"
android:textAllCaps="false"
android:onClick="showShareDemo"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示记住密码功能"
android:textAllCaps="false"
android:onClick="showRememberPassword"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="演示SQLite"
android:textAllCaps="false"
android:onClick="showSQLite"/>
</LinearLayout>
效果图:
activity_share_demo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="请输入"
android:layout_margin="30dp"
android:inputType="text"/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignLeft="@id/editText"
android:layout_below="@id/editText"
android:text="写入"
android:onClick="write"/>
<Button
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignRight="@id/editText"
android:layout_below="@id/editText"
android:text="读取"
android:onClick="read"/>
</RelativeLayout>
效果图:
ShareDemoActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class ShareDemoActivity extends AppCompatActivity {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_demo);
editText = findViewById(R.id.editText);
}
/**
* 写操作,写入的文件的位置是:/data/data/包名/shared_prefs/文件名
* @param view
*/
public void write(View view){
// 1.获取SharePreferences
SharedPreferences sharedPreferences = getSharedPreferences("demo", MODE_PRIVATE); // 私有,仅供该APP使用
// 2.使用SharePreferences写东西
SharedPreferences.Editor editor = sharedPreferences.edit(); // 获取Editor实例
String content = editText.getText().toString();
editor.putString("input", content);
// 3.提交写入
editor.commit();
// 提示
Toast.makeText(this, "写入完毕", Toast.LENGTH_SHORT).show();
}
/**
* 读操作
* @param view
*/
public void read(View view){
// 1.获取SharedPreferences
SharedPreferences sharedPreferences = getSharedPreferences("demo", MODE_PRIVATE);
// 2.读取
String input = sharedPreferences.getString("input", "没有这个值");
// 提示
Toast.makeText(this, "读取到的内容是:" + input,Toast.LENGTH_SHORT).show();
}
}
效果图:
part5:
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 用于展示SharePreferences
* @param view
*/
public void showShareDemo(View view){
Intent intent = new Intent(this, ShareDemoActivity.class);
startActivity(intent);
}
/**
* 用于演示记住密码功能
* @param view
*/
public void showRememberPassword(View view){
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}
/**
* 用于演示SQLite
* @param view
*/
public void showSQLite(View view){
Intent intent = new Intent(this, SQLiteDemoActivity.class);
startActivity(intent);
}
}
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="请输入用户名"
android:inputType="text"
android:layout_marginTop="50dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="50dp"
android:hint="请输入密码"
android:inputType="textPassword"
android:layout_below="@id/username"
android:layout_alignLeft="@id/username"
android:layout_alignRight="@id/username"
android:layout_marginTop="30dp"/>
<CheckBox
android:id="@+id/remember"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"
android:layout_below="@id/password"
android:layout_alignLeft="@id/password"
android:layout_marginTop="20dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="50dp"
android:text="登录"
android:layout_below="@id/remember"
android:layout_alignLeft="@id/password"
android:layout_alignRight="@id/password"
android:layout_marginTop="50dp"
android:onClick="login"/>
</RelativeLayout>
效果图:
LoginActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
//用户名
private EditText username;
//密码
private EditText password;
//记住密码checkbox
private CheckBox isRemember;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
username = findViewById(R.id.username);
password = findViewById(R.id.password);
isRemember = findViewById(R.id.remember);
//前提是用户选择记住密码:填写用户名、密码和勾选记住密码
/*
* user.xml:
* isRemember:boolean
* true:记住密码,false:不记住密码
* username: varchar
* password: varchar
* */
SharedPreferences sharedPreferences = getSharedPreferences("user", MODE_PRIVATE);
boolean remember = sharedPreferences.getBoolean("isRemember", false);
if (remember) {
String usernameString = sharedPreferences.getString("username", "");
username.setText(usernameString);
String passwordString = sharedPreferences.getString("password", "");
password.setText(passwordString);
isRemember.setChecked(true);
}
}
/**
* 登录
* @param view
*/
public void login(View view) {
// admin 123456
String name = username.getText().toString();
String pwd = password.getText().toString();
if ("admin".equals(name) && "123456".equals(pwd)) {
boolean checked = isRemember.isChecked();
SharedPreferences sharedPreferences = getSharedPreferences("user", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
if (checked) {
//写入信息到user
editor.putString("username", name);
editor.putString("password", pwd);
editor.putBoolean("isRemember", checked);
} else {
//清空user信息
editor.putString("username", "");
editor.putString("password", "");
editor.putBoolean("isRemember", checked);
}
editor.commit();
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
} else {
password.setText("");
Toast.makeText(this, "用户名或密码不正确", Toast.LENGTH_SHORT).show();
}
}
}
效果图: