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();
}
}
}
效果圖: