Android之SharedPreferences、引导页、登录页、选项菜单
前言
👨?💻👨?🌾📝记录学习成果,以便温故而知新
Gitee地址https://gitee.com/dycq/AppCode
项目目录

1.MainActivity
此页面没有界面,实现初始化跳转 首先判断是否进行过引导,然后判断是否登录
SharedPreferences appSharedPreferences = getSharedPreferences("APP_DATA", MODE_PRIVATE);
if(!appSharedPreferences.getBoolean("IS_GUIDE", false)) {
Intent intent = new Intent(MainActivity.this, GuideActivity.class);
startActivity(intent);
finish();
return;
}
SharedPreferences userSharedPreferences = getSharedPreferences("USER_DATA", MODE_PRIVATE);
if(!userSharedPreferences.getBoolean("IS_LOGIN", false)) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
} else {
Intent intent = new Intent(MainActivity.this, AppActivity.class);
startActivity(intent);
}
finish();
完整代码
package cn.fy.sharedpreferences;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import cn.fy.sharedpreferences.activity.AppActivity;
import cn.fy.sharedpreferences.activity.GuideActivity;
import cn.fy.sharedpreferences.activity.LoginActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences appSharedPreferences = getSharedPreferences("APP_DATA", MODE_PRIVATE);
if(!appSharedPreferences.getBoolean("IS_GUIDE", false)) {
Intent intent = new Intent(MainActivity.this, GuideActivity.class);
startActivity(intent);
finish();
return;
}
SharedPreferences userSharedPreferences = getSharedPreferences("USER_DATA", MODE_PRIVATE);
if(!userSharedPreferences.getBoolean("IS_LOGIN", false)) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
} else {
Intent intent = new Intent(MainActivity.this, AppActivity.class);
startActivity(intent);
}
finish();
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
2.引导页
(1)效果


 点击“完成”完成引导功能
(2)GuideActivity
代码
package cn.fy.sharedpreferences.activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
import cn.fy.sharedpreferences.databinding.ActivityGuideBinding;
import cn.fy.sharedpreferences.fragment.Frag1Fragment;
import cn.fy.sharedpreferences.fragment.Frag2Fragment;
import cn.fy.sharedpreferences.fragment.Frag3Fragment;
public class GuideActivity extends AppCompatActivity {
private ActivityGuideBinding binding;
List<Class> fragmentList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityGuideBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
fragmentList.add(Frag1Fragment.class);
fragmentList.add(Frag2Fragment.class);
fragmentList.add(Frag3Fragment.class);
binding.vp.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
try {
return (Fragment) fragmentList.get(position).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getItemCount() {
return fragmentList.size();
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.GuideActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
android:layout_marginBottom="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3)3个Fragment
Frag1Fragment代码
package cn.fy.sharedpreferences.fragment;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import cn.fy.sharedpreferences.R;
import cn.fy.sharedpreferences.databinding.FragmentFrag1Binding;
import cn.fy.sharedpreferences.databinding.FragmentFrag3Binding;
public class Frag1Fragment extends Fragment {
private FragmentFrag1Binding binding;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public Frag1Fragment() {
}
public static Frag1Fragment newInstance(String param1, String param2) {
Frag1Fragment fragment = new Frag1Fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentFrag1Binding.inflate(inflater, container, false);
binding.textView1.requestFocus();
return binding.getRoot();
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.Frag1Fragment">
<TextView
android:id="@+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="20dp"
android:text="地振高岗,一派溪山千古秀"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="200dp"
android:text="左划"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Frag2Fragment代码
package cn.fy.sharedpreferences.fragment;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import cn.fy.sharedpreferences.R;
public class Frag2Fragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public Frag2Fragment() {
}
public static Frag2Fragment newInstance(String param1, String param2) {
Frag2Fragment fragment = new Frag2Fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_frag2, container, false);
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frameLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.Frag2Fragment">
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="80dp"
android:layout_marginEnd="20dp"
android:text="门朝大海,三河合水万年流"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="200dp"
android:text="左划"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Frag3Fragment代码
package cn.fy.sharedpreferences.fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import cn.fy.sharedpreferences.MainActivity;
import cn.fy.sharedpreferences.R;
import cn.fy.sharedpreferences.databinding.FragmentFrag3Binding;
public class Frag3Fragment extends Fragment {
private FragmentFrag3Binding binding;
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
public Frag3Fragment() {
}
public static Frag3Fragment newInstance(String param1, String param2) {
Frag3Fragment fragment = new Frag3Fragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentFrag3Binding.inflate(inflater, container, false);
binding.textView6.setClickable(true);
binding.textView6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences appSharedPreferences = getActivity().getSharedPreferences("APP_DATA", Context.MODE_PRIVATE);
appSharedPreferences.edit().putBoolean("IS_GUIDE", true).apply();
Log.i(getClass().getName(), "textView6.setOnClickListener");
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
getActivity().finish();
}
});
binding.textView7.setSelected(true);
return binding.getRoot();
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/frameLayout3"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.Frag3Fragment">
<TextView
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="100dp"
android:layout_marginEnd="20dp"
android:text="青木堂"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginBottom="200dp"
android:text="完成"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/textView7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="80dp"
android:layout_marginEnd="20dp"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="marquee实现效果,内容一定要超过文本框宽度"
android:textColor="#673AB7"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3" />
</androidx.constraintlayout.widget.ConstraintLayout>
(4)marquee
关键代码 fragment_frag3.xml
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="marquee实现效果,内容一定要超过文本框宽度"
Frag3Fragment类onCreateView方法中
binding.textView7.setSelected(true);
3.登录页
效果 点击“登录”,实现登录操作,相关代码
SharedPreferences userSharedPreferences = getSharedPreferences("USER_DATA", MODE_PRIVATE);
userSharedPreferences.edit().putBoolean("IS_LOGIN", true).apply();
完整代码
package cn.fy.sharedpreferences.activity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import cn.fy.sharedpreferences.databinding.ActivityLoginBinding;
public class LoginActivity extends AppCompatActivity {
private ActivityLoginBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.btnReg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(LoginActivity.this, "功能未实现!!!", Toast.LENGTH_SHORT).show();
}
});
binding.btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SharedPreferences userSharedPreferences = getSharedPreferences("USER_DATA", MODE_PRIVATE);
userSharedPreferences.edit().putBoolean("IS_LOGIN", true).apply();
Intent intent = new Intent(LoginActivity.this, AppActivity.class);
startActivity(intent);
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.LoginActivity">
<EditText
android:id="@+id/txt_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="20dp"
android:ems="10"
android:hint="请输入用户名"
android:inputType="textPersonName"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/txt_pwd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="40dp"
android:layout_marginEnd="20dp"
android:ems="10"
android:hint="请输入密码"
android:inputType="textPersonName"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_name" />
<Button
android:id="@+id/btn_reg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginTop="80dp"
android:text="注册"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_pwd" />
<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_marginEnd="60dp"
android:text="登录"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt_pwd" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.应用页
效果 完整代码
package cn.fy.sharedpreferences.activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import cn.fy.sharedpreferences.R;
import cn.fy.sharedpreferences.databinding.ActivityAppBinding;
public class AppActivity extends AppCompatActivity {
private ActivityAppBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityAppBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_options, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_main_options_exit:
AlertDialog.Builder dialog = new AlertDialog.Builder(AppActivity.this);
dialog.setTitle("请确定是否退出");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(AppActivity.this, "功能未实现!!!", Toast.LENGTH_SHORT).show();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.AppActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="100dp"
android:text="APP演示SharedPreferences"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
5.选项菜单
效果 
(1)相关代码
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main_options, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_main_options_exit:
AlertDialog.Builder dialog = new AlertDialog.Builder(AppActivity.this);
dialog.setTitle("请确定是否退出");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(AppActivity.this, "功能未实现!!!", Toast.LENGTH_SHORT).show();
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
}
}).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
(2)菜单代码
建菜单请见三、Android导航篇中“建菜单bottom_navigation_menu” menu_main_options.xml文件
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_main_options_exit"
android:title="退出" />
</menu>
6.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCode">
<activity
android:name=".activity.GuideActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".activity.AppActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".activity.LoginActivity"
android:exported="false">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
|