diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fb7f4a8
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..e9969a1
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..03d404b
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..9aaa431
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,13 @@
+想要成功运行,一定要配置好:
+
+Android Studio版本 (Android Studio Arctic Fox 2020.3.1 Patch 3)
+
+SDK版本(Android 7.0 API24 Revision 2)
+
+Gradle版本(7.0.2)
+
+Android Gradle Plugin版本(7.0.3)
+
+等
+
+本程序由RongLin独立开发,仅用于学习,解释权归RongLin所有!!!
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..9a80f36
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,45 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ compileSdk 30
+
+ defaultConfig {
+ applicationId "com.ronglin.linshopping"
+ minSdk 27
+ targetSdk 30
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ buildFeatures {
+ viewBinding true
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.3.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
+ implementation 'androidx.navigation:navigation-fragment:2.3.5'
+ implementation 'androidx.navigation:navigation-ui:2.3.5'
+ testImplementation 'junit:junit:4.+'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.2'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
new file mode 100644
index 0000000..c418f71
Binary files /dev/null and b/app/release/app-release.apk differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
new file mode 100644
index 0000000..c57c621
--- /dev/null
+++ b/app/release/output-metadata.json
@@ -0,0 +1,20 @@
+{
+ "version": 3,
+ "artifactType": {
+ "type": "APK",
+ "kind": "Directory"
+ },
+ "applicationId": "com.ronglin.linshopping",
+ "variantName": "release",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "attributes": [],
+ "versionCode": 1,
+ "versionName": "1.0",
+ "outputFile": "app-release.apk"
+ }
+ ],
+ "elementType": "File"
+}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/ronglin/linshopping/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/ronglin/linshopping/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..fd2d2f9
--- /dev/null
+++ b/app/src/androidTest/java/com/ronglin/linshopping/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.ronglin.linshopping;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.ronglin.linshopping", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..40a2e13
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/GoodsDialog.java b/app/src/main/java/com/ronglin/linshopping/GoodsDialog.java
new file mode 100644
index 0000000..f31eb4f
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/GoodsDialog.java
@@ -0,0 +1,54 @@
+package com.ronglin.linshopping;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.databinding.DialogGoodsBinding;
+
+public class GoodsDialog extends Dialog implements View.OnClickListener {
+
+ private Goods goods;
+ private Context context;
+ private DialogGoodsBinding binding;
+
+ public GoodsDialog(@NonNull Context context, Goods goods) {
+ super(context);
+ this.goods = goods;
+ this.context = context;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = DialogGoodsBinding.inflate(LayoutInflater.from(context));
+ setContentView(binding.getRoot());
+
+// binding.imageViewPreviewDialog
+ if (goods.getBitmaps().size() > 0){
+ binding.imageViewPreviewDialog.setImageBitmap(goods.getBitmaps().get(0));
+ }
+ binding.getRoot().setOnClickListener(this);
+
+
+ binding.textViewGoodsDescribeDialog.setText(goods.getDescribe());
+
+ binding.textViewGoodsNameDialog.setText(goods.getGoodsName());
+
+ binding.textViewGoodsTagsDialog.setText(goods.getTags().toString());
+
+ binding.textViewGoodsPriceDialog.setText(Goods.toPriceString(goods.getPrice()));
+
+ }
+
+ @Override
+ public void onClick(View view) {
+ hide();
+ }
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/MainActivity.java b/app/src/main/java/com/ronglin/linshopping/MainActivity.java
new file mode 100644
index 0000000..37eb5eb
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/MainActivity.java
@@ -0,0 +1,62 @@
+package com.ronglin.linshopping;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.navigation.ui.AppBarConfiguration;
+import androidx.navigation.ui.NavigationUI;
+
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.application.Person;
+import com.ronglin.linshopping.databinding.ActivityMainBinding;
+import com.ronglin.linshopping.ui.goods.GoodsFragment;
+import com.ronglin.linshopping.ui.person.PersonFragment;
+import com.ronglin.linshopping.ui.person.PersonViewModel;
+import com.ronglin.linshopping.ui.shopping.ShoppingFragment;
+
+import java.util.ArrayList;
+
+public class MainActivity extends AppCompatActivity {
+
+ private ActivityMainBinding binding;
+
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActionBar actionBar=getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.hide();
+ }
+
+ binding = ActivityMainBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ ImageView navView = findViewById(R.id.imageViewPersonPhoto);
+ // Passing each menu ID as a set of Ids because each
+ // menu should be considered as top level destinations.
+ AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
+ R.id.navigation_goods, R.id.navigation_shopping, R.id.navigation_person)
+ .build();
+ NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
+ NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
+ NavigationUI.setupWithNavController(binding.navView, navController);
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/RegisteredActivity.java b/app/src/main/java/com/ronglin/linshopping/RegisteredActivity.java
new file mode 100644
index 0000000..a79b596
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/RegisteredActivity.java
@@ -0,0 +1,73 @@
+package com.ronglin.linshopping;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Toast;
+
+import com.ronglin.linshopping.application.Database;
+import com.ronglin.linshopping.application.MySQLiteHelper;
+import com.ronglin.linshopping.application.Person;
+import com.ronglin.linshopping.databinding.ActivityMainBinding;
+import com.ronglin.linshopping.databinding.RegisteredLayoutBinding;
+
+public class RegisteredActivity extends AppCompatActivity {
+ private RegisteredLayoutBinding registeredLayoutBinding;
+ public static int RESULTCODE_NEWPERSON = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ registeredLayoutBinding = RegisteredLayoutBinding.inflate(getLayoutInflater());
+ setContentView(registeredLayoutBinding.getRoot());
+
+ registeredLayoutBinding.buttonCancelR.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ RegisteredActivity.this.finish();
+ }
+ });
+
+ registeredLayoutBinding.buttonRegistered.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ String userName = registeredLayoutBinding.editTextUsernameR.getText().toString().trim();
+ String password = registeredLayoutBinding.editTextPasswordR.getText().toString().trim();
+ String password2 = registeredLayoutBinding.editTextPasswordR2.getText().toString().trim();
+
+ if (!password.equals(password2)){
+ Toast.makeText(RegisteredActivity.this,"两次密码输入不一致!",Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Database database = new Database(new MySQLiteHelper(RegisteredActivity.this));
+ Person person = database.findPersonFromSQLite(null,userName,password);
+ if (person != null){
+ Toast.makeText(RegisteredActivity.this,"该账号已经注册过了!",Toast.LENGTH_SHORT).show();
+ return;
+ } else {
+ userName = registeredLayoutBinding.editTextUsernameR.getText().toString().trim();
+ password = registeredLayoutBinding.editTextPasswordR.getText().toString().trim();
+
+ person = new Person(userName,password);
+ person.setNum(database.getPersonMaxNumFromSQLite()+1);
+ person.setId(String.valueOf(person.getNum()));
+ person.setMoney(0);
+
+ database.insertPersonToSQLite(person);
+ Toast.makeText(RegisteredActivity.this,"注册成功!",Toast.LENGTH_SHORT).show();
+ Intent intentRegisterSuccess = new Intent();
+ intentRegisterSuccess.putExtra("newPerson",person);
+ setResult(RESULTCODE_NEWPERSON,intentRegisterSuccess);
+ finish();
+ }
+
+
+ }
+ });
+
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/application/BuyingListAdapter.java b/app/src/main/java/com/ronglin/linshopping/application/BuyingListAdapter.java
new file mode 100644
index 0000000..ee94e73
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/BuyingListAdapter.java
@@ -0,0 +1,74 @@
+package com.ronglin.linshopping.application;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.ronglin.linshopping.GoodsDialog;
+import com.ronglin.linshopping.R;
+
+import java.util.ArrayList;
+
+public class BuyingListAdapter extends BaseAdapter {
+ private ArrayList list_goods ;
+ private final Context context;
+
+ public BuyingListAdapter(ArrayList list,Context context){
+ this.list_goods = list;
+ this.context = context;
+ }
+
+ public void setListGoods(ArrayList list){
+ this.list_goods = list;
+ }
+
+ @Override
+ public int getCount() {
+ return list_goods.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return list_goods.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @SuppressLint("ViewHolder")
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ @SuppressLint("ViewHolder") View item_view;
+ item_view = View.inflate(this.context, R.layout.list_item_buying,null);
+
+ ImageView imageViewPreviewBuying = item_view.findViewById(R.id.imageViewPreviewBuying);
+ TextView textViewGoodsNameBuying = item_view.findViewById(R.id.textViewGoodsNameBuying);
+ TextView textViewGoodsPriceBuying = item_view.findViewById(R.id.textViewGoodsPriceBuying);
+
+ item_view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ String t="-"+Goods.toPriceString(list_goods.get(i).getPrice());
+ textViewGoodsPriceBuying.setText(t);
+
+ textViewGoodsNameBuying.setText(list_goods.get(i).getGoodsName());
+
+ if (list_goods.get(i).getBitmaps().size() > 0){
+ imageViewPreviewBuying.setImageBitmap(list_goods.get(i).getBitmaps().get(0));
+ }
+
+
+ return item_view;
+ }
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/Database.java b/app/src/main/java/com/ronglin/linshopping/application/Database.java
new file mode 100644
index 0000000..e354ddf
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/Database.java
@@ -0,0 +1,187 @@
+package com.ronglin.linshopping.application;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class Database {
+ private MySQLiteHelper mySQLiteHelper;
+ private SQLiteDatabase database;
+
+ public Database(MySQLiteHelper mySQLiteHelper){
+ this.mySQLiteHelper = mySQLiteHelper;
+ }
+
+ public void insertPersonToSQLite(Person person){
+ database = mySQLiteHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put("id",person.getId());
+ values.put("num",person.getNum());
+ values.put("username",person.getUsername());
+ values.put("password",person.getPassword());
+ values.put("money",person.getMoney());
+ long id = database.insert("person",null,values);
+ database.close();
+ }
+
+ public int getPersonMaxNumFromSQLite(){
+ database = mySQLiteHelper.getWritableDatabase();
+ int result;
+ Cursor cursor = database.rawQuery("SELECT MAX(num) FROM person",null);
+ if(cursor.getCount() ==0){
+ return 0;
+ } else {
+ cursor.moveToFirst();
+ result = cursor.getInt(0);
+ }
+ return result;
+ }
+
+ public int updatePersonToSQLite(Person person){
+ database = mySQLiteHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put("num",person.getNum());
+ values.put("username",person.getUsername());
+ values.put("password",person.getPassword());
+ values.put("money",person.getMoney());
+ int number = database.update("person",values,"id=?",new String[]{person.getId()});
+ database.close();
+ return number;
+ }
+
+ public int deletePersonToSQLite(Person person){
+ database = mySQLiteHelper.getWritableDatabase();
+ int number = database.delete("person","id =?",new String[]{person.getId()});
+ database.close();
+ return number;
+ }
+
+ //此方法用来查询数据库中是否存在person
+ //优先查询id,id==null,查询username
+ //password为空时返回第一个username的信息 不为空时匹配用户名和密码
+ //当查询不到时返回null
+ public Person findPersonFromSQLite(String id,String username,String password){
+ database = mySQLiteHelper.getReadableDatabase();
+ Person person = new Person(username,null);
+ Cursor cursor ;
+ if(id != null && (!id.isEmpty())){
+ cursor = database.query("person",null,"id=?",new String[]{id},null,null,null);
+ if (cursor.getCount() ==0){
+ database.close();
+ return null;
+ }
+ cursor.moveToFirst();
+ person.setId(cursor.getString(0));
+ person.setNum(cursor.getInt(1));
+ person.setUsername(cursor.getString(2));
+ person.setPassword(cursor.getString(3));
+ person.setMoney(cursor.getInt(4));
+ cursor.close();
+ database.close();
+ return person;
+
+ } else if(username != null && (!username.isEmpty())){
+ cursor = database.query("person",null,"username=?",new String[]{username},null,null,null);
+ if (cursor.getCount() ==0){
+ database.close();
+ return null;
+ } else if(cursor.getCount() ==1){
+ cursor.moveToFirst();
+ if (password != null){
+ if (password.equals(cursor.getString(3))){ //如果密码相等
+ person.setId(cursor.getString(0));
+ person.setNum(cursor.getInt(1));
+ person.setUsername(cursor.getString(2));
+ person.setPassword(cursor.getString(3));
+ person.setMoney(cursor.getInt(4));
+ } else { //如果密码不相等
+ person = null;
+ }
+ } else {
+ person.setId(cursor.getString(0));
+ person.setNum(cursor.getInt(1));
+ person.setUsername(cursor.getString(2));
+ person.setPassword(cursor.getString(3));
+ person.setMoney(cursor.getInt(4));
+ }
+ cursor.close();
+ database.close();
+ return person;
+ } else {
+ cursor.moveToFirst();
+ if (cursor.getString(3).equals(password)){
+ person.setId(cursor.getString(0));
+ person.setNum(cursor.getInt(1));
+ person.setUsername(cursor.getString(2));
+ person.setPassword(cursor.getString(3));
+ person.setMoney(cursor.getInt(4));
+ } else {
+ boolean isExist = false;
+ while(cursor.moveToNext()){
+ if (cursor.getString(3).equals(password)){
+ cursor.moveToFirst();
+ person.setId(cursor.getString(0));
+ person.setNum(cursor.getInt(1));
+ person.setUsername(cursor.getString(2));
+ person.setPassword(cursor.getString(3));
+ person.setMoney(cursor.getInt(4));
+ isExist = true;
+ break;
+ }
+ }
+ if(!isExist) {
+ person = null;
+ }
+ }
+ cursor.close();
+ database.close();
+ return person;
+ }
+
+ }else {
+ database.close();
+ return null;
+ }
+ }
+
+ public void insertGoodsToSQLite(Person person,Goods goods,long time){
+ database = mySQLiteHelper.getWritableDatabase();
+ ContentValues values = new ContentValues();
+ values.put("id",person.getId());
+ values.put("goodsName",goods.getGoodsName());
+ values.put("time",time);
+ long id = database.insert("shopping",null,values);
+ database.close();
+ }
+
+ public int deleteGoodsToSQLite(Person person,Goods goods){
+ database = mySQLiteHelper.getWritableDatabase();
+ int number = database.delete("shopping","id =? and goodsName =?",new String[]{person.getId(),goods.getGoodsName()});
+ database.close();
+ return number;
+ }
+
+ public ArrayList findGoodsListFromSQLite(Person person){
+ database = mySQLiteHelper.getReadableDatabase();
+ ArrayList list = new ArrayList<>();
+ Cursor cursor = database.query("shopping",null,"id=?",new String[]{person.getId()},null,null,null);
+ if (cursor.getCount() == 0){
+ cursor.close();
+ database.close();
+ return list;
+ } else {
+ cursor.moveToFirst();
+ list.add(new String(cursor.getString(1)));
+ while (cursor.moveToNext()){
+ list.add(new String(cursor.getString(1)));
+ }
+ cursor.close();
+ database.close();
+ return list;
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/Goods.java b/app/src/main/java/com/ronglin/linshopping/application/Goods.java
new file mode 100644
index 0000000..7bbe33b
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/Goods.java
@@ -0,0 +1,142 @@
+package com.ronglin.linshopping.application;
+
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import com.ronglin.linshopping.R;
+
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class Goods {
+ private ArrayList bitmaps;
+ private String goodsName;
+ private String describe;
+ private ArrayList tags;
+ private int price;
+
+ public static ArrayList GOODSLIST =new ArrayList<>();
+ public static Goods DEULT_GOODS = new Goods();
+
+ public Goods(){
+ this.bitmaps = new ArrayList<>();
+ this.goodsName = "";
+ this.describe = "";
+ this.tags = new ArrayList<>();
+ this.price = -1;
+ }
+
+ public Goods(String goodsName, String describe, String[] tags, int price){
+ this();
+ this.goodsName = goodsName;
+ this.describe = describe;
+ this.price = price;
+ this.tags.addAll(Arrays.asList(tags));
+ }
+
+ public ArrayList getBitmaps() {
+ return bitmaps;
+ }
+
+ public void setBitmaps(ArrayList bitmaps) {
+ this.bitmaps = bitmaps;
+ }
+
+ public String getGoodsName() {
+ return goodsName;
+ }
+
+ public void setGoodsName(String goodsName) {
+ this.goodsName = goodsName;
+ }
+
+ public String getDescribe() {
+ return describe;
+ }
+
+ public void setDescribe(String describe) {
+ this.describe = describe;
+ }
+
+ public ArrayList getTags() {
+ return tags;
+ }
+
+ public void setTags(ArrayList tags) {
+ this.tags = tags;
+ }
+
+ public int getPrice() {
+ return price;
+ }
+
+ public void setPrice(int price) {
+ this.price = price;
+ }
+
+ public boolean equals(Goods goods){
+ return this.getGoodsName().equals(goods.getGoodsName())
+ && this.getTags().equals(goods.getTags())
+ && this.getDescribe().equals(goods.getDescribe())
+ && this.getPrice() == goods.getPrice();
+ }
+
+ public static String toPriceString(int price){
+ StringBuffer sb = new StringBuffer(String.valueOf(price));
+ //小于2位数
+ if (sb.length()<=2)
+ {
+ if (sb.length() == 0){
+ sb.insert(0,"0.00");
+ } else if(sb.length() == 1){
+ sb.insert(0,"0.0");
+ } else if(sb.length() == 2){
+ sb.insert(0,"0.");
+ }
+ } else {
+ sb.insert(sb.length()-2,'.');
+ }
+ return sb.toString();
+ }
+
+ public static void getDefaultGoodsList(Context context){
+
+ GOODSLIST.clear();
+ Goods goods1 = new Goods("人字拖","夏季人字拖,清凉一夏",new String[]{"板鞋","凉鞋","人字拖"},5000);
+ goods1.setDescribe("夏季人字拖,清凉一夏,夏季人字拖,清凉一夏,夏季人字拖,清凉一夏,夏季人字拖,清凉一夏,夏季人字拖,清凉一夏");
+ Goods goods2 = new Goods("莱布尼茨篮球","好篮球就是它",new String[]{"篮球","莱布尼茨"},30000);
+ goods2.setDescribe("好篮球就是它,他就是好篮球!好篮球就是它,他就是好篮球!好篮球就是它,他就是好篮球!好篮球就是它,他就是好篮球!");
+ Goods goods3 = new Goods("尼龙克斯羽毛球拍","夏季球拍,神挡杀神",new String[]{"羽毛球拍","尼龙克斯"},15000);
+ goods3.setDescribe("夏季球拍,神挡杀神,买下此拍,让你的羽毛球技术增加几倍,买下此拍,让你的羽毛球技术增加几倍!!!");
+ Goods goods4 = new Goods("常德大拖鞋","应急拖鞋,紧急备用",new String[]{"凉鞋"},100);
+ goods4.setDescribe("应急拖鞋,紧急备用,应急拖鞋,紧急备用,应急拖鞋,紧急备用,应急拖鞋,紧急备用,应急拖鞋,紧急备用,应急拖鞋,紧急备用");
+
+ ArrayList bitmaps1 = new ArrayList<>();
+ bitmaps1.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.renzituo));
+ goods1.setBitmaps(bitmaps1);
+
+ ArrayList bitmaps2 = new ArrayList<>();
+ bitmaps2.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.liangxie));
+ goods2.setBitmaps(bitmaps2);
+
+ ArrayList bitmaps3 = new ArrayList<>();
+ bitmaps3.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.pixue));
+ goods3.setBitmaps(bitmaps3);
+
+ ArrayList bitmaps4 = new ArrayList<>();
+ bitmaps4.add(BitmapFactory.decodeResource(context.getResources(), R.drawable.tuoxie));
+ goods4.setBitmaps(bitmaps4);
+
+
+ GOODSLIST.add(goods1);
+ GOODSLIST.add(goods2);
+ GOODSLIST.add(goods3);
+ GOODSLIST.add(goods4);
+ }
+
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/GoodsListAdapter.java b/app/src/main/java/com/ronglin/linshopping/application/GoodsListAdapter.java
new file mode 100644
index 0000000..ea74892
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/GoodsListAdapter.java
@@ -0,0 +1,151 @@
+package com.ronglin.linshopping.application;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.ronglin.linshopping.GoodsDialog;
+import com.ronglin.linshopping.R;
+import com.ronglin.linshopping.ui.person.PersonFragment;
+import com.ronglin.linshopping.ui.shopping.ShoppingFragment;
+
+import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class GoodsListAdapter extends BaseAdapter{
+ private ArrayList list_goods;
+ private final Context context;
+ private boolean delay = false;
+
+// private final ListItemGoodsBinding listItemGoodsBinding;
+
+ public GoodsListAdapter(ArrayList list, Context context){
+ this.list_goods = list;
+ this.context = context;
+// listItemGoodsBinding =ListItemGoodsBinding.inflate(LayoutInflater.from(context));
+ }
+
+ public void setListGoods(ArrayList list){
+ this.list_goods = list;
+ }
+
+ @Override
+ public int getCount() {
+ return list_goods.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return list_goods.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @SuppressLint("ViewHolder")
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ @SuppressLint("ViewHolder") View item_view;
+ item_view = View.inflate(this.context, R.layout.list_item_goods,null);
+// View item_view = listItemGoodsBinding.getRoot();
+ //设置列表的显示形式
+ ImageView imageViewPreview = item_view.findViewById(R.id.imageViewPreview);
+ TextView textViewGoodsName = item_view.findViewById(R.id.textViewGoodsName);
+ TextView textViewGoodsTags = item_view.findViewById(R.id.textViewGoodsTags);
+ TextView textViewPrice = item_view.findViewById(R.id.textViewPrice);
+ ImageButton imageButtonAdd = item_view.findViewById(R.id.imageButtonAdd);
+
+ imageViewPreview.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(GoodsListAdapter.this.context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ textViewGoodsName.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(GoodsListAdapter.this.context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ textViewGoodsTags.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(GoodsListAdapter.this.context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ textViewPrice.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(GoodsListAdapter.this.context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+
+
+ if (list_goods.get(i).getBitmaps().size() > 0){
+ imageViewPreview.setImageBitmap(list_goods.get(i).getBitmaps().get(0));
+ }
+ textViewGoodsName.setText(list_goods.get(i).getGoodsName());
+ textViewGoodsTags.setText(list_goods.get(i).getTags().toString());
+
+ textViewPrice.setText(Goods.toPriceString(list_goods.get(i).getPrice()));
+
+
+ imageButtonAdd.setOnClickListener(new View.OnClickListener() {
+ @SuppressLint("UseCompatLoadingForDrawables")
+ @Override
+ public void onClick(View view) {
+
+
+ if(!PersonFragment.ISLOGIN){
+ Toast.makeText(context,"请先登录",Toast.LENGTH_SHORT).show();
+ }else{
+ if (!delay){
+ ShoppingFragment.shoppingList.add(Goods.GOODSLIST.get(i));
+ Toast.makeText(context,"添加成功",Toast.LENGTH_SHORT).show();
+ delay = true;
+ imageButtonAdd.setImageResource(R.drawable.ok);
+
+ @SuppressLint("HandlerLeak") Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ delay=false;
+ imageButtonAdd.setImageResource(R.drawable.shopping_add);
+ }
+ };
+ TimerTask task = new TimerTask(){
+ public void run() {
+ Message message = new Message();
+ mHandler.sendMessage(message);
+ }
+ };
+ Timer timer = new Timer();
+ timer.schedule(task, 1000);
+
+ }
+ }
+
+ }
+ });
+ return item_view;
+ }
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/MySQLiteHelper.java b/app/src/main/java/com/ronglin/linshopping/application/MySQLiteHelper.java
new file mode 100644
index 0000000..129c115
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/MySQLiteHelper.java
@@ -0,0 +1,26 @@
+package com.ronglin.linshopping.application;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import androidx.annotation.Nullable;
+
+public class MySQLiteHelper extends SQLiteOpenHelper {
+ public MySQLiteHelper(@Nullable Context context) {
+ super(context,"LinShopping.db", null, 1);
+ }
+
+
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase) {
+ sqLiteDatabase.execSQL("create table person(id varchar(10) primary key,num integer,username varchar(30),password varchar(30),money integer)");
+ sqLiteDatabase.execSQL("create table shopping(id varchar(10),goodsName varchar(30),time bigint)");
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
+
+ }
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/Person.java b/app/src/main/java/com/ronglin/linshopping/application/Person.java
new file mode 100644
index 0000000..cc4131d
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/Person.java
@@ -0,0 +1,64 @@
+package com.ronglin.linshopping.application;
+
+import java.io.Serializable;
+
+public class Person implements Serializable {
+ private String id;
+ private int num;
+ private String username;
+ private String password;
+ private int money =0 ;
+
+ public Person(String name, String password){
+ this.username = name;
+ this.password = password;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setNum(int num) {
+ this.num = num;
+ }
+
+ public int getNum() {
+ return num;
+ }
+
+ public int getMoney() {
+ return money;
+ }
+
+ public void setMoney(int money) {
+ this.money = money;
+ }
+
+ public String toString(){
+ String t;
+ t ="{id:%s,num:%s,username:%s,password:%s,money:%s}";
+ t =String.format(t,this.id,this.num,this.username,this.password,this.money);
+ return t;
+ }
+
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/application/ShoppingListAdapter.java b/app/src/main/java/com/ronglin/linshopping/application/ShoppingListAdapter.java
new file mode 100644
index 0000000..39bc4c7
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/application/ShoppingListAdapter.java
@@ -0,0 +1,133 @@
+package com.ronglin.linshopping.application;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.ronglin.linshopping.GoodsDialog;
+import com.ronglin.linshopping.R;
+import com.ronglin.linshopping.databinding.FragmentShoppingBinding;
+import com.ronglin.linshopping.databinding.ListItemGoodsBinding;
+import com.ronglin.linshopping.databinding.ListItemShoppingBinding;
+
+import java.util.ArrayList;
+
+public class ShoppingListAdapter extends BaseAdapter {
+
+ private ArrayList list_goods ;
+ private static ArrayList list_select = new ArrayList<>();
+ private int allPrice = 0;
+ private final Context context;
+ private FragmentShoppingBinding binding;
+
+ public ShoppingListAdapter(ArrayList list, Context context, FragmentShoppingBinding binding){
+ this.list_goods = list;
+ this.context = context;
+ this.binding = binding;
+ }
+
+ public void setListGoods(ArrayList list){
+ this.list_goods = list;
+ }
+
+ public void setSelectList(ArrayList list){
+ this.list_select = list;
+ }
+
+ public ArrayList getSelectList(){
+ return this.list_select;
+ }
+
+ @Override
+ public int getCount() {
+ return list_goods.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return list_goods.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @SuppressLint("ViewHolder")
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ @SuppressLint("ViewHolder") View item_view;
+ item_view = View.inflate(this.context, R.layout.list_item_shopping,null);
+
+ CheckBox checkBoxSelect = item_view.findViewById(R.id.checkBoxSelect);
+ ImageView imageViewPreviewShopping = item_view.findViewById(R.id.imageViewPreviewShopping);
+ TextView textViewGoodsNameShopping = item_view.findViewById(R.id.textViewGoodsNameShopping);
+ TextView textViewGoodsPriceShopping = item_view.findViewById(R.id.textViewGoodsPriceShopping);
+
+ //被选中了就显示选中
+ if (list_select.contains(i)){
+ checkBoxSelect.setChecked(true);
+ }
+
+ checkBoxSelect.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (checkBoxSelect.isChecked()){
+ list_select.add(i);
+ } else {
+ list_select.remove(Integer.valueOf(i));
+ }
+
+ allPrice = 0;
+
+ for (int i=0;i 0){
+ imageViewPreviewShopping.setImageBitmap(list_goods.get(i).getBitmaps().get(0));
+ }
+ imageViewPreviewShopping.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ textViewGoodsNameShopping.setText(list_goods.get(i).getGoodsName());
+ textViewGoodsNameShopping.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ textViewGoodsPriceShopping.setText(Goods.toPriceString(list_goods.get(i).getPrice()));
+ textViewGoodsPriceShopping.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ GoodsDialog dialog = new GoodsDialog(context,list_goods.get(i));
+ dialog.show();
+ }
+ });
+
+ return item_view;
+ }
+}
diff --git a/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsFragment.java b/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsFragment.java
new file mode 100644
index 0000000..c5e036d
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsFragment.java
@@ -0,0 +1,139 @@
+package com.ronglin.linshopping.ui.goods;
+
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.navigation.Navigation;
+
+import com.ronglin.linshopping.R;
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.application.GoodsListAdapter;
+import com.ronglin.linshopping.databinding.FragmentGoodsBinding;
+
+import java.util.ArrayList;
+
+
+public class GoodsFragment extends Fragment {
+
+ private GoodsViewModel goodsViewModel;
+ private FragmentGoodsBinding binding;
+ private ArrayList list;
+ private ArrayList resultList;
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ goodsViewModel =
+ new ViewModelProvider(this).get(GoodsViewModel.class);
+
+ binding = FragmentGoodsBinding.inflate(inflater, container, false);
+ View root = binding.getRoot();
+
+ list = new ArrayList<>();
+ resultList = new ArrayList<>();
+
+ initListView();
+ initGoodsFragment();
+
+
+ return root;
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+ }
+
+
+ private void initGoodsFragment(){
+ binding.topBar.imageButtonPhoto.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Navigation.findNavController(GoodsFragment.this.getView()).navigate(R.id.navigation_person);
+ }
+ });
+ binding.topBar.imageButtonShopping.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Navigation.findNavController(GoodsFragment.this.getView()).navigate(R.id.navigation_shopping);
+ }
+ });
+
+ binding.topBar.editTextSearch.addTextChangedListener(new TextWatcher() {
+ /*
+ beforeTextChanged(CharSequence s, int start, int count, int after)
+ s: 修改之前的文字。
+ start: 字符串中即将发生修改的位置。
+ count: 字符串中即将被修改的文字的长度。如果是新增的话则为0。
+ after: 被修改的文字修改之后的长度。如果是删除的话则为0。
+ onTextChanged(CharSequence s, int start, int before, int count)
+ s: 改变后的字符串
+ start: 有变动的字符串的序号
+ before: 被改变的字符串长度,如果是新增则为0。
+ count: 添加的字符串长度,如果是删除则为0。
+ afterTextChanged(Editable s)
+ s: 修改后的文字
+ */
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ String search = s.toString().trim();
+ if(search.isEmpty()){
+ goodsViewModel.setListGoods(list);
+ } else {
+ resultList.clear();
+ for (Goods t:list) {
+ if(t.getGoodsName().contains(search)){
+ resultList.add(t);
+ } else if (t.getTags().toString().contains(search)){
+ resultList.add(t);
+ } else if (t.getDescribe().contains(search)){
+ resultList.add(t);
+ }
+ }
+ goodsViewModel.setListGoods(resultList);
+ }
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+
+ }
+ });
+
+ }
+
+ private void initListView(){
+ if (Goods.GOODSLIST.size() == 0){
+ Goods.getDefaultGoodsList(getContext());
+ }
+ list = new ArrayList<>(Goods.GOODSLIST);
+
+ goodsViewModel.setListGoods(list);
+ GoodsListAdapter goodsListAdapter = new GoodsListAdapter(list,this.getContext());
+ binding.listViewGoods.setAdapter(goodsListAdapter);
+
+ goodsViewModel.getListGoods().observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(ArrayList list) {
+ goodsListAdapter.setListGoods(list);
+ binding.listViewGoods.setAdapter(goodsListAdapter);
+ }
+ });
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsViewModel.java b/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsViewModel.java
new file mode 100644
index 0000000..844e877
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/ui/goods/GoodsViewModel.java
@@ -0,0 +1,26 @@
+package com.ronglin.linshopping.ui.goods;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import com.ronglin.linshopping.application.Goods;
+
+import java.util.ArrayList;
+
+public class GoodsViewModel extends ViewModel {
+
+ private final MutableLiveData> list_goods;
+
+ public GoodsViewModel() {
+ list_goods = new MutableLiveData<>();
+ }
+
+ public LiveData> getListGoods() {
+ return list_goods;
+ }
+
+ public void setListGoods(ArrayList list){
+ this.list_goods.setValue(list);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/ui/person/PersonFragment.java b/app/src/main/java/com/ronglin/linshopping/ui/person/PersonFragment.java
new file mode 100644
index 0000000..9e1ff89
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/ui/person/PersonFragment.java
@@ -0,0 +1,268 @@
+package com.ronglin.linshopping.ui.person;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.ronglin.linshopping.RegisteredActivity;
+import com.ronglin.linshopping.application.BuyingListAdapter;
+import com.ronglin.linshopping.application.Database;
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.application.MySQLiteHelper;
+import com.ronglin.linshopping.application.Person;
+import com.ronglin.linshopping.databinding.FragmentPersonBinding;
+
+import java.util.ArrayList;
+
+public class PersonFragment extends Fragment {
+
+ private PersonViewModel personViewModel;
+ private FragmentPersonBinding binding;
+ public static boolean ISLOGIN = false;
+ public static int REQUESTCODE_NEWPERSON = 1;
+ public static Person person;
+ private ArrayList goodsArrayList = new ArrayList<>();
+ private BuyingListAdapter buyingListAdapter;
+
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ personViewModel =
+ new ViewModelProvider(this).get(PersonViewModel.class);
+
+ binding = FragmentPersonBinding.inflate(inflater, container, false);
+ View root = binding.getRoot();
+
+ if (!ISLOGIN){
+ binding.linearLayoutLogin.setVisibility(View.VISIBLE);
+ binding.linearLayoutLoginSuccess.setVisibility(View.GONE);
+ } else
+ {
+ binding.linearLayoutLogin.setVisibility(View.GONE);
+ binding.linearLayoutLoginSuccess.setVisibility(View.VISIBLE);
+
+ goodsArrayList.clear();
+ Database database = new Database(new MySQLiteHelper(getContext()));
+ ArrayList goodsNameList = database.findGoodsListFromSQLite(person);
+ for (String t:goodsNameList
+ ) {
+ for (Goods goods:Goods.GOODSLIST
+ ) {
+ if (t.equals(goods.getGoodsName())){
+ goodsArrayList.add(goods);
+ }
+ }
+ }
+
+ }
+
+
+ personViewModel.getPerson().observe(getViewLifecycleOwner(), new Observer() {
+ @Override
+ public void onChanged(@Nullable Person person) {
+ if (person != null){
+ PersonFragment.person = person;
+
+ binding.includeLogin.editTextUsername.setText(person.getUsername());
+ binding.includeLogin.editTextPassword.setText(person.getPassword());
+
+ binding.includeLoginSuccess.textViewPersonName.setText(person.getUsername());
+
+ //购物清单也要跟着变
+ Database database = new Database(new MySQLiteHelper(getContext()));
+ ArrayList goodsNameList = database.findGoodsListFromSQLite(person);
+ ArrayList goodsArrayList = new ArrayList<>();
+ for (String t:goodsNameList
+ ) {
+ for (Goods goods:Goods.GOODSLIST
+ ) {
+ if (t.equals(goods.getGoodsName())){
+ goodsArrayList.add(goods);
+ }
+ }
+ }
+ personViewModel.setBuyingList(goodsArrayList);
+ }
+ }
+ });
+
+ personViewModel.setBuyingList(goodsArrayList);
+ buyingListAdapter = new BuyingListAdapter(goodsArrayList,getContext());
+ binding.includeLoginSuccess.buyingListView.setAdapter(buyingListAdapter);
+
+ personViewModel.getBuyingList().observe(getViewLifecycleOwner(), new Observer>(){
+ @Override
+ public void onChanged(ArrayList list) {
+ buyingListAdapter.setListGoods(list);
+ binding.includeLoginSuccess.buyingListView.setAdapter(buyingListAdapter);
+ }
+ });
+
+
+ initLayoutLogin();
+ initLayoutLoginSuccess();
+ return root;
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+// String result = (personViewModel.getPerson().getValue() == null)?"null":personViewModel.getPerson().getValue().toString();
+// Log.i("TAG", "onDestroyView: "+result);
+ }
+
+
+ public void initLayoutLogin(){
+ if (personViewModel.getPerson().getValue() != null){
+ binding.includeLogin.editTextUsername.setText(personViewModel.getPerson().getValue().getUsername());
+ }
+
+ binding.includeLogin.buttonRegistered.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent intentStartRegistered = new Intent(getActivity(), RegisteredActivity.class);
+ startActivityForResult(intentStartRegistered,REQUESTCODE_NEWPERSON);
+ }
+ });
+ binding.includeLogin.buttonLogin.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ String userName = binding.includeLogin.editTextUsername.getText().toString().trim();
+ String password = binding.includeLogin.editTextPassword.getText().toString().trim();
+
+ if (userName.isEmpty()){
+ Toast.makeText(getContext(), "请输入用户名", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ if (password.isEmpty()){
+ Toast.makeText(getContext(), "请输入密码", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ Database database = new Database(new MySQLiteHelper(getContext()));
+ Person person = database.findPersonFromSQLite(null,userName,password);
+ if (person == null){
+ Toast.makeText(getContext(), "用户名或密码错误,请核对后重新输入", Toast.LENGTH_SHORT).show();
+ return;
+ } else {
+ personViewModel.setPerson(person);
+ binding.includeLoginSuccess.textViewPersonName.setText(personViewModel.getPerson().getValue().getUsername());
+ StringBuffer sb = new StringBuffer(String.valueOf(personViewModel.getPerson().getValue().getMoney()));
+ //小于2位数
+ if (sb.length()<=2)
+ {
+ if (sb.length() == 0){
+ sb.insert(0,"0.00");
+ } else if(sb.length() == 1){
+ sb.insert(0,"0.0");
+ } else if(sb.length() == 2){
+ sb.insert(0,"0.");
+ }
+ } else {
+ sb.insert(sb.length()-2,'.');
+ }
+ binding.includeLoginSuccess.textViewPersonMoney.setText(sb.toString());
+ ISLOGIN = true;
+ binding.linearLayoutLogin.setVisibility(View.GONE);
+ binding.linearLayoutLoginSuccess.setVisibility(View.VISIBLE);
+
+ goodsArrayList.clear();
+ ArrayList goodsNameList = database.findGoodsListFromSQLite(person);
+ for (String t:goodsNameList
+ ) {
+ for (Goods goods:Goods.GOODSLIST
+ ) {
+ if (t.equals(goods.getGoodsName())){
+ goodsArrayList.add(goods);
+ }
+ }
+ }
+ personViewModel.setBuyingList(goodsArrayList);
+ Log.i("TAG", "onClick: "+person.toString());
+ }
+ }
+ });
+
+
+ }
+
+ public void initLayoutLoginSuccess(){
+ if (personViewModel.getPerson().getValue() != null){
+ binding.includeLoginSuccess.textViewPersonName.setText(personViewModel.getPerson().getValue().getUsername());
+
+ StringBuffer sb = new StringBuffer(String.valueOf(personViewModel.getPerson().getValue().getMoney()));
+ //小于2位数
+ if (sb.length()<=2)
+ {
+ if (sb.length() == 0){
+ sb.insert(0,"0.00");
+ } else if(sb.length() == 1){
+ sb.insert(0,"0.0");
+ } else if(sb.length() == 2){
+ sb.insert(0,"0.");
+ }
+ } else {
+ sb.insert(sb.length()-2,'.');
+ }
+ binding.includeLoginSuccess.textViewPersonMoney.setText(sb.toString());
+ }
+
+ binding.includeLoginSuccess.buttonEsc.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ binding.linearLayoutLoginSuccess.setVisibility(View.GONE);
+ binding.linearLayoutLogin.setVisibility(View.VISIBLE);
+
+ if (personViewModel.getPerson().getValue()!= null){
+ binding.includeLogin.editTextUsername.setText(personViewModel.getPerson().getValue().getUsername());
+ binding.includeLogin.editTextPassword.setText(personViewModel.getPerson().getValue().getPassword());
+ }
+
+ ISLOGIN = false;
+
+ }
+ });
+
+ binding.includeLoginSuccess.buttonCharge.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Toast.makeText(getContext(),"充值成功",Toast.LENGTH_SHORT).show();
+ Person person = personViewModel.getPerson().getValue();
+ person.setMoney(person.getMoney()+10000);
+ Database database = new Database(new MySQLiteHelper(getContext()));
+ database.updatePersonToSQLite(person);
+ personViewModel.setPerson(person);
+
+ binding.includeLoginSuccess.textViewPersonMoney.setText(Goods.toPriceString(personViewModel.getPerson().getValue().getMoney()));
+ }
+ });
+
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == PersonFragment.REQUESTCODE_NEWPERSON){
+ if (resultCode == RegisteredActivity.RESULTCODE_NEWPERSON){
+ Person person =(Person) data.getSerializableExtra("newPerson");
+// Navigation.findNavController(MainActivity.this.binding.getRoot()).navigate(R.id.navigation_person);
+ personViewModel = new ViewModelProvider(this).get(PersonViewModel.class);
+ personViewModel.setPerson(person);
+// Log.i("MainActivity", "onActivityResult: "+personViewModel.getPerson().toString());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/ui/person/PersonViewModel.java b/app/src/main/java/com/ronglin/linshopping/ui/person/PersonViewModel.java
new file mode 100644
index 0000000..2ed746b
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/ui/person/PersonViewModel.java
@@ -0,0 +1,42 @@
+package com.ronglin.linshopping.ui.person;
+
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.ViewModel;
+
+import com.ronglin.linshopping.application.Database;
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.application.Person;
+
+import java.util.ArrayList;
+
+public class PersonViewModel extends ViewModel {
+
+ private MutableLiveData personMutableLiveData;
+ private MutableLiveData> buyingListMutableLiveData;
+
+ public PersonViewModel() {
+ personMutableLiveData = new MutableLiveData<>();
+ buyingListMutableLiveData = new MutableLiveData<>();
+ buyingListMutableLiveData.setValue(new ArrayList<>());
+ personMutableLiveData.setValue(PersonFragment.person); //从MainActivity中恢复数据
+ }
+
+ public void setPerson(Person person){
+ personMutableLiveData.setValue(person);
+ PersonFragment.person = person; //防止Fragment销毁的时候数据也被清空
+
+ }
+
+ public LiveData getPerson() {
+ return personMutableLiveData;
+ }
+
+ public void setBuyingList(ArrayList list){
+ buyingListMutableLiveData.setValue(list);
+ }
+
+ public LiveData> getBuyingList() {
+ return buyingListMutableLiveData;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/ronglin/linshopping/ui/shopping/ShoppingFragment.java b/app/src/main/java/com/ronglin/linshopping/ui/shopping/ShoppingFragment.java
new file mode 100644
index 0000000..e6b9167
--- /dev/null
+++ b/app/src/main/java/com/ronglin/linshopping/ui/shopping/ShoppingFragment.java
@@ -0,0 +1,211 @@
+package com.ronglin.linshopping.ui.shopping;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.ronglin.linshopping.R;
+import com.ronglin.linshopping.application.Database;
+import com.ronglin.linshopping.application.Goods;
+import com.ronglin.linshopping.application.MySQLiteHelper;
+import com.ronglin.linshopping.application.Person;
+import com.ronglin.linshopping.application.ShoppingListAdapter;
+import com.ronglin.linshopping.databinding.FragmentShoppingBinding;
+import com.ronglin.linshopping.ui.person.PersonFragment;
+import com.ronglin.linshopping.ui.person.PersonViewModel;
+
+import java.util.ArrayList;
+
+public class ShoppingFragment extends Fragment {
+
+ private ShoppingViewModel shoppingViewModel;
+ private FragmentShoppingBinding binding;
+ private PersonViewModel personViewModel;
+ private ShoppingListAdapter shoppingListAdapter;
+ public static ArrayList shoppingList = new ArrayList<>();
+
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ shoppingViewModel =
+ new ViewModelProvider(this).get(ShoppingViewModel.class);
+
+ personViewModel = new ViewModelProvider(this).get(PersonViewModel.class);
+
+ binding = FragmentShoppingBinding.inflate(inflater, container, false);
+ View root = binding.getRoot();
+
+ initShoppingList();
+
+ return root;
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+ }
+
+ private void initShoppingList(){
+ shoppingViewModel.setShoppingList(shoppingList);
+ shoppingListAdapter = new ShoppingListAdapter(shoppingList,getContext(),binding);
+ binding.listViewShopping.setAdapter(shoppingListAdapter);
+ if (PersonFragment.ISLOGIN){
+
+ shoppingViewModel.getShoppingList().observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(@Nullable ArrayList list) {
+ ShoppingFragment.shoppingList = list;
+ shoppingListAdapter.setListGoods(list);
+ binding.listViewShopping.setAdapter(shoppingListAdapter);
+ }
+ });
+
+
+ binding.shoppingBottom.buttonDelete.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //从购物列表中删除选中的项目
+ deleteListWithIndex(shoppingViewModel.getShoppingList().getValue(),shoppingListAdapter.getSelectList());
+ shoppingListAdapter.getSelectList().clear();
+ shoppingViewModel.setShoppingList(shoppingViewModel.getShoppingList().getValue());
+
+ binding.shoppingBottom.textViewAllPrice.setText("0.00");
+ Toast.makeText(ShoppingFragment.this.getContext(),"删除成功",Toast.LENGTH_SHORT).show();
+ }
+
+ });
+
+ binding.shoppingBottom.checkBoxAll.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (binding.shoppingBottom.checkBoxAll.isChecked()){
+ shoppingListAdapter.getSelectList().clear();
+
+ for(int i=0;i list,ArrayList indexList){
+ for (int i=0;i> shoppingList;
+
+ public ShoppingViewModel() {
+ shoppingList = new MutableLiveData<>();
+ }
+
+ public void setShoppingList(ArrayList list){
+ this.shoppingList.setValue(list);
+ ShoppingFragment.shoppingList = list;
+ }
+
+ public LiveData> getShoppingList() {
+ return shoppingList;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bottom_navigation_item_selector.xml b/app/src/main/res/drawable/bottom_navigation_item_selector.xml
new file mode 100644
index 0000000..75cebd1
--- /dev/null
+++ b/app/src/main/res/drawable/bottom_navigation_item_selector.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/default_goods.png b/app/src/main/res/drawable/default_goods.png
new file mode 100644
index 0000000..c50b261
Binary files /dev/null and b/app/src/main/res/drawable/default_goods.png differ
diff --git a/app/src/main/res/drawable/default_person.png b/app/src/main/res/drawable/default_person.png
new file mode 100644
index 0000000..fedae73
Binary files /dev/null and b/app/src/main/res/drawable/default_person.png differ
diff --git a/app/src/main/res/drawable/default_photo.png b/app/src/main/res/drawable/default_photo.png
new file mode 100644
index 0000000..31f60b7
Binary files /dev/null and b/app/src/main/res/drawable/default_photo.png differ
diff --git a/app/src/main/res/drawable/goods.png b/app/src/main/res/drawable/goods.png
new file mode 100644
index 0000000..0f298e6
Binary files /dev/null and b/app/src/main/res/drawable/goods.png differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/liangxie.jpeg b/app/src/main/res/drawable/liangxie.jpeg
new file mode 100644
index 0000000..c9aec74
Binary files /dev/null and b/app/src/main/res/drawable/liangxie.jpeg differ
diff --git a/app/src/main/res/drawable/ok.png b/app/src/main/res/drawable/ok.png
new file mode 100644
index 0000000..e2a7e0b
Binary files /dev/null and b/app/src/main/res/drawable/ok.png differ
diff --git a/app/src/main/res/drawable/person.png b/app/src/main/res/drawable/person.png
new file mode 100644
index 0000000..2f45898
Binary files /dev/null and b/app/src/main/res/drawable/person.png differ
diff --git a/app/src/main/res/drawable/photo.jpg b/app/src/main/res/drawable/photo.jpg
new file mode 100644
index 0000000..3372cfb
Binary files /dev/null and b/app/src/main/res/drawable/photo.jpg differ
diff --git a/app/src/main/res/drawable/pixue.jpeg b/app/src/main/res/drawable/pixue.jpeg
new file mode 100644
index 0000000..b7fc068
Binary files /dev/null and b/app/src/main/res/drawable/pixue.jpeg differ
diff --git a/app/src/main/res/drawable/question.png b/app/src/main/res/drawable/question.png
new file mode 100644
index 0000000..99ee679
Binary files /dev/null and b/app/src/main/res/drawable/question.png differ
diff --git a/app/src/main/res/drawable/renzituo.jpeg b/app/src/main/res/drawable/renzituo.jpeg
new file mode 100644
index 0000000..10d2000
Binary files /dev/null and b/app/src/main/res/drawable/renzituo.jpeg differ
diff --git a/app/src/main/res/drawable/search.png b/app/src/main/res/drawable/search.png
new file mode 100644
index 0000000..33f7333
Binary files /dev/null and b/app/src/main/res/drawable/search.png differ
diff --git a/app/src/main/res/drawable/sharp_edit.xml b/app/src/main/res/drawable/sharp_edit.xml
new file mode 100644
index 0000000..ad4cc0b
--- /dev/null
+++ b/app/src/main/res/drawable/sharp_edit.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/shopping.png b/app/src/main/res/drawable/shopping.png
new file mode 100644
index 0000000..d2e28af
Binary files /dev/null and b/app/src/main/res/drawable/shopping.png differ
diff --git a/app/src/main/res/drawable/shopping2.png b/app/src/main/res/drawable/shopping2.png
new file mode 100644
index 0000000..c537178
Binary files /dev/null and b/app/src/main/res/drawable/shopping2.png differ
diff --git a/app/src/main/res/drawable/shopping_add.png b/app/src/main/res/drawable/shopping_add.png
new file mode 100644
index 0000000..8fe3f8a
Binary files /dev/null and b/app/src/main/res/drawable/shopping_add.png differ
diff --git a/app/src/main/res/drawable/text_view_tags.xml b/app/src/main/res/drawable/text_view_tags.xml
new file mode 100644
index 0000000..940455c
--- /dev/null
+++ b/app/src/main/res/drawable/text_view_tags.xml
@@ -0,0 +1,17 @@
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
diff --git a/app/src/main/res/drawable/tuoxie.jpeg b/app/src/main/res/drawable/tuoxie.jpeg
new file mode 100644
index 0000000..eba295d
Binary files /dev/null and b/app/src/main/res/drawable/tuoxie.jpeg differ
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..8189107
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_goods.xml b/app/src/main/res/layout/dialog_goods.xml
new file mode 100644
index 0000000..2a2a889
--- /dev/null
+++ b/app/src/main/res/layout/dialog_goods.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_goods.xml b/app/src/main/res/layout/fragment_goods.xml
new file mode 100644
index 0000000..9077817
--- /dev/null
+++ b/app/src/main/res/layout/fragment_goods.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_person.xml b/app/src/main/res/layout/fragment_person.xml
new file mode 100644
index 0000000..895cabe
--- /dev/null
+++ b/app/src/main/res/layout/fragment_person.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_shopping.xml b/app/src/main/res/layout/fragment_shopping.xml
new file mode 100644
index 0000000..5dc04d7
--- /dev/null
+++ b/app/src/main/res/layout/fragment_shopping.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_buying.xml b/app/src/main/res/layout/list_item_buying.xml
new file mode 100644
index 0000000..4936eb7
--- /dev/null
+++ b/app/src/main/res/layout/list_item_buying.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_goods.xml b/app/src/main/res/layout/list_item_goods.xml
new file mode 100644
index 0000000..2790260
--- /dev/null
+++ b/app/src/main/res/layout/list_item_goods.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_item_shopping.xml b/app/src/main/res/layout/list_item_shopping.xml
new file mode 100644
index 0000000..5e54fa1
--- /dev/null
+++ b/app/src/main/res/layout/list_item_shopping.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_layout.xml b/app/src/main/res/layout/login_layout.xml
new file mode 100644
index 0000000..6e73edf
--- /dev/null
+++ b/app/src/main/res/layout/login_layout.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_success_layout.xml b/app/src/main/res/layout/login_success_layout.xml
new file mode 100644
index 0000000..ef565d0
--- /dev/null
+++ b/app/src/main/res/layout/login_success_layout.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/registered_layout.xml b/app/src/main/res/layout/registered_layout.xml
new file mode 100644
index 0000000..315635d
--- /dev/null
+++ b/app/src/main/res/layout/registered_layout.xml
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/shopping_bottom.xml b/app/src/main/res/layout/shopping_bottom.xml
new file mode 100644
index 0000000..99b1461
--- /dev/null
+++ b/app/src/main/res/layout/shopping_bottom.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/top_bar.xml b/app/src/main/res/layout/top_bar.xml
new file mode 100644
index 0000000..543aac5
--- /dev/null
+++ b/app/src/main/res/layout/top_bar.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml
new file mode 100644
index 0000000..17f38e5
--- /dev/null
+++ b/app/src/main/res/menu/bottom_nav_menu.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
new file mode 100644
index 0000000..3e76456
--- /dev/null
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..ef4d188
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..a6b55c3
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,15 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+ #FFBB86FC
+ #FFBB86FC
+ #4169E1
+ #000000
+ #FFFF0000
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..e00c2dd
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..823bcab
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+ 高午商店
+ 商品
+ 购物车
+ 个人中心
+ 请输入商品名称
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1d83a87
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,17 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/ronglin/linshopping/ExampleUnitTest.java b/app/src/test/java/com/ronglin/linshopping/ExampleUnitTest.java
new file mode 100644
index 0000000..3a2d4f3
--- /dev/null
+++ b/app/src/test/java/com/ronglin/linshopping/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.ronglin.linshopping;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..7cbb664
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,17 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath "com.android.tools.build:gradle:7.0.3"
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..31942d4
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+android.overridePathCheck=true
+android.injected.testOnly = false
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..f53ee09
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Nov 29 18:57:08 CST 2021
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..43485b9
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,10 @@
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ jcenter() // Warning: this repository is going to shut down soon
+ }
+}
+rootProject.name = "LinShopping"
+include ':app'