diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file 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/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..70f212e --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,414 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dictionaries/snow.xml b/.idea/dictionaries/snow.xml new file mode 100644 index 0000000..ed85c9e --- /dev/null +++ b/.idea/dictionaries/snow.xml @@ -0,0 +1,10 @@ + + + + fujian + gson + guangxi + shuyue + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..6e5389e --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..41a25ff --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2763af --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ 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..2cd4448 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,57 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 31 + buildToolsVersion "30.0.0" + + defaultConfig { + applicationId "com.shuyue.snack" + minSdkVersion 21 + targetSdkVersion 31 + versionCode 2 + versionName '1.1' + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + // ButterKnife requires Java 8. + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.navigation:navigation-fragment:2.3.0' + implementation 'androidx.navigation:navigation-ui:2.3.0' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.mediarouter:mediarouter:1.1.0' + testImplementation 'junit:junit:4.13' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + + // 引入ButterKnife依赖 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + + // 引入BaseRecyclerViewAdapterHelper库 + implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4' + + // 引入CircleImageView照片库 + implementation 'de.hdodenhof:circleimageview:3.1.0' + + // 引入Gson库 + implementation 'com.google.code.gson:gson:2.8.6' +} 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/src/androidTest/java/com/android/jingdong/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/android/jingdong/ExampleInstrumentedTest.java new file mode 100644 index 0000000..ac94db9 --- /dev/null +++ b/app/src/androidTest/java/com/android/jingdong/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.android.jingdong; + +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.shuyue.snack", 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..78f8479 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/MainActivity.java b/app/src/main/java/com/android/jingdong/MainActivity.java new file mode 100644 index 0000000..b8f0696 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/MainActivity.java @@ -0,0 +1,49 @@ +package com.android.jingdong; + +import android.os.Bundle; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import com.google.android.material.bottomnavigation.BottomNavigationView; +import com.android.jingdong.dao.UserDao; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + BottomNavigationView navView = findViewById(R.id.nav_view); + // 将每个菜单ID作为一组ID传递 5.27 + // 因为每个菜单都应该被视为顶级路径 + AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( + R.id.navigation_home, R.id.navigation_snack, R.id.navigation_place, R.id.navigation_my) + .build(); + NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); + NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); + NavigationUI.setupWithNavController(navView, navController); + + // 检查登录状态 + checkLogin(); + } + + /** + * 检查是否有登录信息 + */ + private void checkLogin() { + // 检查持久化的数据 + if (UserDao.isLogin()) { + // 已登录 + MyApplication.isLogin(true); + MyApplication.setUser(UserDao.getUser()); + } else { + // 未登录 + MyApplication.isLogin(false); + MyApplication.setUser(null); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/MyApplication.java b/app/src/main/java/com/android/jingdong/MyApplication.java new file mode 100644 index 0000000..34cdbf1 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/MyApplication.java @@ -0,0 +1,73 @@ +package com.android.jingdong; + +import android.app.Application; + +import com.android.jingdong.model.JD; +import com.android.jingdong.model.User; +import com.android.jingdong.utils.Utils; + +import java.util.ArrayList; +import java.util.List; + +public class MyApplication extends Application { + + /** + * Application类上下文 + */ + private static MyApplication appContext; + + /** + * 购物车的乐器 + */ + private static List cartJDS; + + /** + * 登录用户 + */ + private static User user; + + /** + * 登录状态 + */ + private static boolean isLogin; + + public static MyApplication getInstance() { + return appContext; + } + + public static List getCartTaobaos() { + return cartJDS; + } + + public static User getUser() { + return user; + } + + public static void setUser(User user) { + MyApplication.user = user; + } + + /** + * 是否登录 + * + * @return true: 已经登录, false: 未登录 + */ + public static boolean isLogin() { + return isLogin; + } + + public static void isLogin(boolean isLogin) { + MyApplication.isLogin = isLogin; + } + + @Override + public void onCreate() { + super.onCreate(); + appContext = this; + // 初始化购物车集合 + cartJDS = new ArrayList<>(); + + // 初始化工具类 + Utils.init(this); + } +} diff --git a/app/src/main/java/com/android/jingdong/activity/DetailActivity.java b/app/src/main/java/com/android/jingdong/activity/DetailActivity.java new file mode 100644 index 0000000..c2c2a0e --- /dev/null +++ b/app/src/main/java/com/android/jingdong/activity/DetailActivity.java @@ -0,0 +1,117 @@ +package com.android.jingdong.activity; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.appcompat.app.AppCompatActivity; + +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.model.JD; +import com.android.jingdong.utils.Tips; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class DetailActivity extends AppCompatActivity { + + @BindView(R.id.detailImage) + ImageView image; + + @BindView(R.id.detailName) + TextView name; + + @BindView(R.id.detailPrice) + TextView price; + + @BindView(R.id.detailContent) + TextView detail; + + @BindView(R.id.detailAddCartBtn) + Button addCart; + + @BindView(R.id.detailFavorite) + ImageView favorite; + + public static void actionStart(Context context, JD JD) { + Intent intent = new Intent(context, DetailActivity.class); + intent.putExtra("JD", JD); + context.startActivity(intent); + } + + @SuppressLint("SetTextI18n") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail); + + fullScreen(this); + + ButterKnife.bind(this); + + JD JD = (JD) getIntent().getSerializableExtra("JD"); + + if (JD != null) { + image.setImageResource(JD.getImage()); + name.setText(JD.getName()); + price.setText("¥" + JD.getPrice()); + detail.setText(JD.getDetail()); + + addCart.setOnClickListener(v -> { + if (!MyApplication.getCartTaobaos().contains(JD)) { + // 添加到购物车 + JD.setCount(1); + MyApplication.getCartTaobaos().add(JD); + Tips.show("已添加" + JD.getName() + "到购物车"); + + // 关闭Activity + finish(); + } else { + Tips.show("已在购物车中,不能重复添加"); + } + }); + } + } + + @OnClick(R.id.detailBack) + void clickBack() { + finish(); + } + + @OnClick(R.id.detailFavorite) + void clickFavorite() { + favorite.setImageResource(R.drawable.ic_baseline_favorite_24dp); + } + + /** + * 通过设置全屏,设置状态栏透明 + */ + private void fullScreen(Activity activity) { + Window window = activity.getWindow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + View decorView = ((Window) window).getDecorView(); + int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + decorView.setSystemUiVisibility(option); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(Color.TRANSPARENT); + } else { + WindowManager.LayoutParams attributes = window.getAttributes(); + int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; + attributes.flags |= flagTranslucentStatus; + window.setAttributes(attributes); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/activity/LoginActivity.java b/app/src/main/java/com/android/jingdong/activity/LoginActivity.java new file mode 100644 index 0000000..5bff069 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/activity/LoginActivity.java @@ -0,0 +1,101 @@ +package com.android.jingdong.activity; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.EditText; + +import androidx.appcompat.app.AppCompatActivity; + +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.dao.UserDao; +import com.android.jingdong.data.DataServer; +import com.android.jingdong.model.User; +import com.android.jingdong.utils.Tips; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class LoginActivity extends AppCompatActivity { + + @BindView(R.id.loginUsernameEdit) + EditText usernameEdit; + + @BindView(R.id.loginPasswordEdit) + EditText passwordEdit; + + public static void actionStart(Context context) { + Intent intent = new Intent(context, LoginActivity.class); + context.startActivity(intent); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + + setTitle("登录"); + + ButterKnife.bind(this); + + // 恢复账号 + String username = UserDao.getUsername(); + usernameEdit.setText(username); + } + + @Override + protected void onStop() { + super.onStop(); + finish(); + } + + /** + * 登录按钮点击事件 + */ + @OnClick(R.id.loginBtn) + void login() { + String username = usernameEdit.getText().toString(); + String password = passwordEdit.getText().toString(); + User user = new User(username, password); + + User loginUser = checkUserFromAccountList(user); + if (loginUser != null) { + // 登录成功 + Tips.show("登录成功"); + + MyApplication.isLogin(true); + MyApplication.setUser(loginUser); + + // 持久化已登录用户数据 + UserDao.saveUser(loginUser); + UserDao.isLogin(true); + + // 持久化账号,以便退出登录后不用再输入账号 + UserDao.saveUsername(username); + + // 关闭Activity + finish(); + } else { + // 登录失败 + Tips.show("登录失败"); + passwordEdit.setText(""); + } + } + + /** + * 登录 + * + * @return 登录成功: 查询到的用户对象, 登录失败: null + */ + public User checkUserFromAccountList(User u) { + for (User tmp : DataServer.getAccountList()) { + if (tmp.equals(u)) { + return tmp; + } + } + + return null; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/activity/OrderActivity.java b/app/src/main/java/com/android/jingdong/activity/OrderActivity.java new file mode 100644 index 0000000..9cedfd9 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/activity/OrderActivity.java @@ -0,0 +1,65 @@ +package com.android.jingdong.activity; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.adaptor.OrderAdapter; +import com.android.jingdong.dao.OrderDao; +import com.android.jingdong.model.Order; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class OrderActivity extends AppCompatActivity { + + @BindView(R.id.orderRecyclerView) + RecyclerView orderRecyclerView; + + public static void actionStart(Context context) { + Intent intent = new Intent(context, OrderActivity.class); + context.startActivity(intent); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_order); + + setTitle("订单"); + + ButterKnife.bind(this); + + orderRecyclerView.setLayoutManager(new LinearLayoutManager(OrderActivity.this)); + + initAdapter(); + } + + /** + * 初始化订单页面 + */ + private void initAdapter() { + // 获取数据库数据 + List orders = OrderDao.findAllByUsername(MyApplication.getUser().getUsername()); + + OrderAdapter adapter = new OrderAdapter(orders); + + // 设置空布局 + adapter.setEmptyView(getEmptyView()); + + orderRecyclerView.setAdapter(adapter); + } + + public View getEmptyView() { + return getLayoutInflater().inflate(R.layout.empty_order_view, orderRecyclerView, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/activity/WelcomeActivity.java b/app/src/main/java/com/android/jingdong/activity/WelcomeActivity.java new file mode 100644 index 0000000..97d4419 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/activity/WelcomeActivity.java @@ -0,0 +1,35 @@ +package com.android.jingdong.activity; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; + +import androidx.appcompat.app.AppCompatActivity; + +import com.android.jingdong.MainActivity; +import com.android.jingdong.R; + +public class WelcomeActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_welcome); + + View decorView = getWindow().getDecorView(); + // Hide the status bar. + int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN; + decorView.setSystemUiVisibility(uiOptions); + + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + Intent intent = new Intent(WelcomeActivity.this, MainActivity.class); + startActivity(intent); + + finish(); + } + }, 800); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/adaptor/HomeAdapter.java b/app/src/main/java/com/android/jingdong/adaptor/HomeAdapter.java new file mode 100644 index 0000000..abffaf1 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/adaptor/HomeAdapter.java @@ -0,0 +1,22 @@ +package com.android.jingdong.adaptor; + +import com.android.jingdong.model.JD; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.android.jingdong.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class HomeAdapter extends BaseQuickAdapter { + + public HomeAdapter(List JDS) { + super(R.layout.item_home_snack, JDS); + } + + @Override + protected void convert(@NotNull BaseViewHolder baseViewHolder, JD JD) { + baseViewHolder.setImageResource(R.id.homeSnackImage, JD.getImage()); + } +} diff --git a/app/src/main/java/com/android/jingdong/adaptor/OrderAdapter.java b/app/src/main/java/com/android/jingdong/adaptor/OrderAdapter.java new file mode 100644 index 0000000..85b56e9 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/adaptor/OrderAdapter.java @@ -0,0 +1,28 @@ +package com.android.jingdong.adaptor; + +import android.annotation.SuppressLint; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.android.jingdong.R; +import com.android.jingdong.model.Order; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class OrderAdapter extends BaseQuickAdapter { + + public OrderAdapter(List orders) { + super(R.layout.item_order, orders); + } + + @SuppressLint("SimpleDateFormat") + @Override + protected void convert(@NotNull BaseViewHolder baseViewHolder, Order order) { + baseViewHolder.setText(R.id.orderName, order.getName()); + baseViewHolder.setImageResource(R.id.orderImage, order.getImage()); + baseViewHolder.setText(R.id.orderTime, "下单时间: " + order.getTime()); + baseViewHolder.setText(R.id.orderMoney, "总价: ¥" + order.getMoney()); + } +} diff --git a/app/src/main/java/com/android/jingdong/adaptor/PlaceOrderAdapter.java b/app/src/main/java/com/android/jingdong/adaptor/PlaceOrderAdapter.java new file mode 100644 index 0000000..2fd875b --- /dev/null +++ b/app/src/main/java/com/android/jingdong/adaptor/PlaceOrderAdapter.java @@ -0,0 +1,28 @@ +package com.android.jingdong.adaptor; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.android.jingdong.R; +import com.android.jingdong.model.JD; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * 下单页面购物车列表适配器 + */ +public class PlaceOrderAdapter extends BaseQuickAdapter { + + public PlaceOrderAdapter(List JDS) { + super(R.layout.item_place_order, JDS); + } + + @Override + protected void convert(@NotNull BaseViewHolder baseViewHolder, JD JD) { + baseViewHolder.setImageResource(R.id.placeOrderImage, JD.getImage()) + .setText(R.id.placeOrderName, JD.getName()) + .setText(R.id.placeOrderPrice, "¥" + JD.getPrice()) + .setText(R.id.orderCountBtn, String.valueOf(JD.getCount())); + } +} diff --git a/app/src/main/java/com/android/jingdong/adaptor/TaobaoLeftAdapter.java b/app/src/main/java/com/android/jingdong/adaptor/TaobaoLeftAdapter.java new file mode 100644 index 0000000..f44e0ae --- /dev/null +++ b/app/src/main/java/com/android/jingdong/adaptor/TaobaoLeftAdapter.java @@ -0,0 +1,29 @@ +package com.android.jingdong.adaptor; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.android.jingdong.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class TaobaoLeftAdapter extends BaseQuickAdapter { + + public TaobaoLeftAdapter(List types) { + super(R.layout.item_taobao_left, types); + } + + /** + * 设置item数据 + */ + @Override + protected void convert(@NotNull BaseViewHolder baseViewHolder, String s) { + // 第一个item默认选中状态 +// if (baseViewHolder.getLayoutPosition() == 0) { +// baseViewHolder.setBackgroundResource(R.id.snackLeftType, R.color.colorBgWhite); +// } + baseViewHolder.setText(R.id.snackLeftType, s); + } + +} diff --git a/app/src/main/java/com/android/jingdong/adaptor/TaobaoRightAdapter.java b/app/src/main/java/com/android/jingdong/adaptor/TaobaoRightAdapter.java new file mode 100644 index 0000000..5fec983 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/adaptor/TaobaoRightAdapter.java @@ -0,0 +1,24 @@ +package com.android.jingdong.adaptor; + +import com.android.jingdong.model.JD; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.viewholder.BaseViewHolder; +import com.android.jingdong.R; + +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class TaobaoRightAdapter extends BaseQuickAdapter { + + public TaobaoRightAdapter(List JDS) { + super(R.layout.item_taobao_right, JDS); + } + + @Override + protected void convert(@NotNull BaseViewHolder baseViewHolder, JD JD) { + baseViewHolder.setImageResource(R.id.snackRightImage, JD.getImage()) + .setText(R.id.snackRightName, JD.getName()) + .setText(R.id.snackRightPrice, "¥" + JD.getPrice()); + } +} diff --git a/app/src/main/java/com/android/jingdong/animator/MyAnimation.java b/app/src/main/java/com/android/jingdong/animator/MyAnimation.java new file mode 100644 index 0000000..ddaf1c2 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/animator/MyAnimation.java @@ -0,0 +1,29 @@ +package com.android.jingdong.animator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +import com.chad.library.adapter.base.animation.BaseAnimation; + +import org.jetbrains.annotations.NotNull; + +public class MyAnimation implements BaseAnimation { + @NotNull + @Override + public Animator[] animators(@NotNull View view) { + Animator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1.3f, 1); + Animator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1.3f, 1); + Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); + + scaleY.setDuration(350); + scaleX.setDuration(350); + alpha.setDuration(350); + + scaleY.setInterpolator(new DecelerateInterpolator()); + scaleX.setInterpolator(new DecelerateInterpolator()); + + return new Animator[]{scaleY, scaleX, alpha}; + } +} diff --git a/app/src/main/java/com/android/jingdong/animator/MyAnimation2.java b/app/src/main/java/com/android/jingdong/animator/MyAnimation2.java new file mode 100644 index 0000000..cd017a4 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/animator/MyAnimation2.java @@ -0,0 +1,37 @@ +package com.android.jingdong.animator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.Interpolator; + +import com.chad.library.adapter.base.animation.BaseAnimation; + +import org.jetbrains.annotations.NotNull; + +import static java.lang.Math.PI; +import static java.lang.Math.pow; +import static java.lang.Math.sin; + +public class MyAnimation2 implements BaseAnimation { + + static class MyInterpolator2 implements Interpolator { + @Override + public float getInterpolation(float input) { + float factor = 0.7f; + return (float) (pow(2.0, -10.0 * input) * sin((input - factor / 4) * (2 * PI) / factor) + 1); + } + } + + @NotNull + @Override + public Animator[] animators(@NotNull View view) { + Animator translationX = + ObjectAnimator.ofFloat(view, "translationX", -view.getRootView().getWidth(), 0f); + + translationX.setDuration(800); + translationX.setInterpolator(new MyInterpolator2()); + + return new Animator[]{translationX}; + } +} diff --git a/app/src/main/java/com/android/jingdong/animator/MyAnimation3.java b/app/src/main/java/com/android/jingdong/animator/MyAnimation3.java new file mode 100644 index 0000000..7b40192 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/animator/MyAnimation3.java @@ -0,0 +1,27 @@ +package com.android.jingdong.animator; + +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +import com.chad.library.adapter.base.animation.BaseAnimation; + +import org.jetbrains.annotations.NotNull; + +public class MyAnimation3 implements BaseAnimation { + + @NotNull + @Override + public Animator[] animators(@NotNull View view) { + Animator alpha = ObjectAnimator.ofFloat(view, "alpha", 0, 1f); + alpha.setDuration(450); + + Animator translationY = + ObjectAnimator.ofFloat(view, "translationY", view.getRootView().getHeight(), 0f); + translationY.setDuration(450); + translationY.setInterpolator(new DecelerateInterpolator(1.2f)); + + return new Animator[]{alpha, translationY}; + } +} diff --git a/app/src/main/java/com/android/jingdong/dao/DatabaseHelper.java b/app/src/main/java/com/android/jingdong/dao/DatabaseHelper.java new file mode 100644 index 0000000..640d911 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/dao/DatabaseHelper.java @@ -0,0 +1,33 @@ +package com.android.jingdong.dao; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import androidx.annotation.Nullable; + +public class DatabaseHelper extends SQLiteOpenHelper { + + public DatabaseHelper(@Nullable Context context, int version) { + super(context, " ", null, version); + } + + @Override + public void onCreate(SQLiteDatabase db) { + // 创建数据库 + String createOrders = "create table orders (" + + "id integer primary key autoincrement," + + "name text," + + "image integer," + + "money real," + + "time text," + + "username text)"; + + db.execSQL(createOrders); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + + } +} diff --git a/app/src/main/java/com/android/jingdong/dao/OrderDao.java b/app/src/main/java/com/android/jingdong/dao/OrderDao.java new file mode 100644 index 0000000..260c946 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/dao/OrderDao.java @@ -0,0 +1,62 @@ +package com.android.jingdong.dao; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.android.jingdong.model.Order; +import com.android.jingdong.utils.Utils; + +import java.util.ArrayList; +import java.util.List; + +public class OrderDao { + + private static DatabaseHelper dbHelper = new DatabaseHelper(Utils.getContext(), 1); + + static { + dbHelper.getWritableDatabase(); + } + + /** + * 保存订单数据 + */ + public static void saveOrder(List orders) { + SQLiteDatabase db = dbHelper.getWritableDatabase(); + for (Order order : orders) { + ContentValues values = new ContentValues(); + values.put("name", order.getName()); + values.put("image", order.getImage()); + values.put("money", order.getMoney()); + values.put("time", order.getTime()); + values.put("username", order.getUsername()); + + db.insert("orders", null, values); + } + } + + /** + * 通过用户名查询订单数据 + */ + public static List findAllByUsername(String username) { + SQLiteDatabase db = dbHelper.getWritableDatabase(); + List orders = new ArrayList<>(); + + // 查询指定用户名订单 + Cursor cursor = db.query("orders", null, "username=?", new String[]{username}, null, null, "time desc"); + if (cursor.moveToFirst()) { + do { + String name = cursor.getString(cursor.getColumnIndex("name")); + int image = cursor.getInt(cursor.getColumnIndex("image")); + double money = cursor.getDouble(cursor.getColumnIndex("money")); + String time = cursor.getString(cursor.getColumnIndex("time")); + + Order order = new Order(name, image, money, time); + orders.add(order); + } while (cursor.moveToNext()); + } + cursor.close(); + + return orders; + } +} diff --git a/app/src/main/java/com/android/jingdong/dao/UserDao.java b/app/src/main/java/com/android/jingdong/dao/UserDao.java new file mode 100644 index 0000000..55ee638 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/dao/UserDao.java @@ -0,0 +1,71 @@ +package com.android.jingdong.dao; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.google.gson.Gson; +import com.android.jingdong.model.User; +import com.android.jingdong.utils.Utils; + +public class UserDao { + + // 实例化SharedPreferences对象 + private static SharedPreferences data = Utils.getContext().getSharedPreferences("data", Context.MODE_PRIVATE); + + // Gson对象 + private static Gson gson = new Gson(); + + public static boolean isLogin() { + return data.getBoolean("isLogin", false); + } + + public static void isLogin(boolean bool) { + SharedPreferences.Editor edit = data.edit(); + edit.putBoolean("isLogin", bool); + edit.apply(); + } + + /** + * 获取已登录用户对象 + */ + public static User getUser() { + String userJson = data.getString("user", ""); + return gson.fromJson(userJson, User.class); + } + + public static void saveUser(User user) { + String userJson = gson.toJson(user); + SharedPreferences.Editor edit = data.edit(); + edit.putString("user", userJson); + edit.apply(); + } + + /** + * 清除登录用户信息和登录状态 + */ + public static void removeUserAndLoginStatus() { + SharedPreferences.Editor edit = data.edit(); + edit.remove("user"); + edit.remove("isLogin"); + edit.apply(); + } + + public static void removeAll() { + SharedPreferences.Editor edit = data.edit(); + edit.clear(); + edit.apply(); + } + + /** + * 保存账号 + */ + public static void saveUsername(String username) { + SharedPreferences.Editor editor = data.edit(); + editor.putString("username", username); + editor.apply(); + } + + public static String getUsername() { + return data.getString("username", ""); + } +} diff --git a/app/src/main/java/com/android/jingdong/data/DataServer.java b/app/src/main/java/com/android/jingdong/data/DataServer.java new file mode 100644 index 0000000..3b4f77a --- /dev/null +++ b/app/src/main/java/com/android/jingdong/data/DataServer.java @@ -0,0 +1,156 @@ +package com.android.jingdong.data; + + +import android.annotation.SuppressLint; + +import com.android.jingdong.model.JD; +import com.android.jingdong.model.Order; +import com.android.jingdong.R; +import com.android.jingdong.model.User; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class DataServer { + + private static List snackOrderList; + + private static List homeList; + + private static List fujianList; + + private static List guangxiList; + + private static List guangzhouList; + + private static List beijingList; + + private static List chongqingList; + + private static List accountList; + + /** + * 首页数据 + */ + public static List getHomeList() { + if (homeList == null) { + homeList = new ArrayList() {{ + add(new JD("苹果13", 5999, R.mipmap.sp1, "苹果13一般指iPhone 13。 iPhone 13是美国苹果公司于北京时间2021年9月15日凌晨1点在Apple Park发布的iPhone手机。")); + add(new JD("华为mate40", 5888, R.mipmap.sp2, "华为Mate40一般指HUAWEI Mate 40。 HUAWEI Mate 40是华为公司于2020年10月22日发布的手机,于2020年12月21日上市。")); + add(new JD("联想Y9000P", 8999, R.mipmap.sp3, "联想Y9000P采用了双面金属设计,搭载16英寸四边窄边框屏,2560*1600 分辨率,165Hz刷新率,500nit亮度,100%sRGB色域,HDR400认证,支持杜比视界。")); + add(new JD("暗影精灵8", 8699, R.mipmap.sp4, "暗影精灵8 Plus,搭载全新i7处理器,全系标配DDR5 4800MHz双通道内存,还有游戏级PCle 4.0 SSD加持,游戏载入少等待、尽情存储少焦虑。")); + add(new JD("海盗船K100", 1299, R.mipmap.sp5, "海盗船K100键盘采用的是悬浮式按键设计,搭配高品质精密二色注塑PBT透光键帽,1.5mm的厚度超耐用,防滑性能很好,使用手感非常赞。")); + add(new JD("罗技G502", 229, R.mipmap.sp6, "罗技G502游戏鼠标,在配重,平衡及追踪表面的适应性需要有更好的提升,尽可能满足每一位玩家的精确需求。")); + + }}; + } + return homeList; + } + + /** + * 点菜页面分类左边列表数据 + */ + public static List getSnackOrderList() { + if (snackOrderList == null) { + snackOrderList = new ArrayList() {{ + add("手机"); + add("电脑"); + add("电子配件"); +// add("鼠标"); +// add("耳机"); + }}; + } + return snackOrderList; + } + + /** + * 手机 + */ + public static List getFujianList() { + if (fujianList == null) { + fujianList = new ArrayList() {{ + add(new JD("苹果13", 5999, R.mipmap.sp1, "苹果13一般指iPhone 13。 iPhone 13是美国苹果公司于北京时间2021年9月15日凌晨1点在Apple Park发布的iPhone手机。")); + add(new JD("华为mate40", 5888, R.mipmap.sp2, "华为Mate40一般指HUAWEI Mate 40。 HUAWEI Mate 40是华为公司于2020年10月22日发布的手机,于2020年12月21日上市。")); + + }}; + } + return fujianList; + } + + /** + * 电脑 + */ + public static List getGuangxiList() { + if (guangxiList == null) { + guangxiList = new ArrayList() {{ + add(new JD("联想Y9000P", 8999, R.mipmap.sp3, "联想Y9000P采用了双面金属设计,搭载16英寸四边窄边框屏,2560*1600 分辨率,165Hz刷新率,500nit亮度,100%sRGB色域,HDR400认证,支持杜比视界。")); + add(new JD("暗影精灵8", 8699, R.mipmap.sp4, "暗影精灵8 Plus,搭载全新i7处理器,全系标配DDR5 4800MHz双通道内存,还有游戏级PCle 4.0 SSD加持,游戏载入少等待、尽情存储少焦虑。")); + }}; + } + return guangxiList; + } + + /** + * 配件 + */ + public static List getGuangzhouList() { + if (guangzhouList == null) { + guangzhouList = new ArrayList() {{ + add(new JD("海盗船K100", 1299, R.mipmap.sp5, "海盗船K100键盘采用的是悬浮式按键设计,搭配高品质精密二色注塑PBT透光键帽,1.5mm的厚度超耐用,防滑性能很好,使用手感非常赞。")); + add(new JD("罗技G502", 229, R.mipmap.sp6, "罗技G502游戏鼠标,在配重,平衡及追踪表面的适应性需要有更好的提升,尽可能满足每一位玩家的精确需求。")); + }}; + } + return guangzhouList; + } + +// /** +// * 鼠标 +// */ +// public static List getBeijingList() { +// if (beijingList == null) { +// beijingList = new ArrayList() {{ +// +// }}; +// } +// return beijingList; +// } +// +// /** +// * 耳机 +// */ +// public static List getChongqingList() { +// if (chongqingList == null) { +// chongqingList = new ArrayList() {{ +// +// }}; +// } +// return chongqingList; +// } + + /** + * 用户账号信息 + */ + public static List getAccountList() { + if (accountList == null) { + accountList = new ArrayList() {{ + add(new User("123456", "123", "小新", R.drawable.one4)); + }}; + } + return accountList; + } + + + + + + public static List getOrderTest() { + @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return new ArrayList() {{ + add(new Order("是我", R.mipmap.user1_head, 10.9, simpleDateFormat.format(new Date()))); + add(new Order("是我", R.mipmap.user1_head, 10.9, simpleDateFormat.format(new Date()))); + add(new Order("是我", R.mipmap.user1_head, 10.9, simpleDateFormat.format(new Date()))); + }}; + } +} diff --git a/app/src/main/java/com/android/jingdong/model/JD.java b/app/src/main/java/com/android/jingdong/model/JD.java new file mode 100644 index 0000000..4970b4f --- /dev/null +++ b/app/src/main/java/com/android/jingdong/model/JD.java @@ -0,0 +1,121 @@ +package com.android.jingdong.model; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.Objects; + +/** + * 乐器类 + */ +public class JD implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 商品名称 + */ + private String name; + + /** + * 商品单价 + */ + private double price; + + /** + * 图片资源 + */ + private int image; + + /** + * 商品详情 + */ + private String detail; + + /** + * 商品数量 + */ + private int count; + + public JD() { + } + + public JD(String name, double price, int image, String detail) { + this.name = name; + this.price = price; + this.image = image; + this.detail = detail; + this.count = 1; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public int getImage() { + return image; + } + + public void setImage(int image) { + this.image = image; + } + + public String getDetail() { + return detail; + } + + public void setDetail(String detail) { + this.detail = detail; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + /** + * 重写equals方法 用于比较商品是否已添加到购物车 + * + * @param o 待比较商品对象 + * @return 比较结果 + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + JD JD = (JD) o; + return Objects.equals(name, JD.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @NotNull + @Override + public String toString() { + return "JD{" + + "name='" + name + '\'' + + ", price=" + price + + ", image=" + image + + ", detail='" + detail + '\'' + + ", count=" + count + + '}'; + } +} diff --git a/app/src/main/java/com/android/jingdong/model/Order.java b/app/src/main/java/com/android/jingdong/model/Order.java new file mode 100644 index 0000000..15ec6a1 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/model/Order.java @@ -0,0 +1,104 @@ +package com.android.jingdong.model; + +import android.annotation.SuppressLint; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Order implements Serializable { + + private static final long serialVersionUID = 1L; + + private String name; + + private int image; + + private double money; + + private String time; + + private String username; + + public Order() { + } + + public Order(String name, int image, double money, String time) { + this.name = name; + this.image = image; + this.money = money; + this.time = time; + } + + /** + * 乐器类导入订单 + * 计算金额、加入订单产生时间 + * + * @param JD 产生的乐器对象 + */ + @SuppressLint("SimpleDateFormat") + public Order(JD JD) { + this.name = JD.getName(); + this.image = JD.getImage(); + // 计算金额 + BigDecimal money = BigDecimal.valueOf(JD.getPrice()).multiply(BigDecimal.valueOf(JD.getCount())); + this.money = money.doubleValue(); + // 订单产生时间(格式化) + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + this.time = simpleDateFormat.format(new Date()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getImage() { + return image; + } + + public void setImage(int image) { + this.image = image; + } + + public double getMoney() { + return money; + } + + public void setMoney(double money) { + this.money = money; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + @NotNull + @Override + public String toString() { + return "Order{" + + "name='" + name + '\'' + + ", image='" + image + '\'' + + ", money=" + money + + ", time=" + time + + '}'; + } +} diff --git a/app/src/main/java/com/android/jingdong/model/User.java b/app/src/main/java/com/android/jingdong/model/User.java new file mode 100644 index 0000000..f4c6224 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/model/User.java @@ -0,0 +1,108 @@ +package com.android.jingdong.model; + +import org.jetbrains.annotations.NotNull; + +import java.io.Serializable; +import java.util.Objects; + +public class User implements Serializable { + + private static final long serialVersionUID = 1L; + + private int id; + + private String username; + + private String password; + + private String nickname; + + private int headImage; + + public User() { + } + + public User(String username, String password) { + this.username = username; + this.password = password; + } + + public User(String username, String password, String nickname, int headImage) { + this.username = username; + this.password = password; + this.nickname = nickname; + this.headImage = headImage; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + 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 getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public int getHeadImage() { + return headImage; + } + + public void setHeadImage(int headImage) { + this.headImage = headImage; + } + + /** + * 用于登录比较用户账号密码 + * + * @param o 待比较用户 + * @return 比较结果 + */ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(username, user.username) && + Objects.equals(password, user.password); + } + + @Override + public int hashCode() { + return Objects.hash(username, password); + } + + @NotNull + @Override + public String toString() { + return "User{" + + "id=" + id + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", nickname='" + nickname + '\'' + + ", headImage='" + headImage + '\'' + + '}'; + } +} diff --git a/app/src/main/java/com/android/jingdong/ui/JD/TaobaoFragment.java b/app/src/main/java/com/android/jingdong/ui/JD/TaobaoFragment.java new file mode 100644 index 0000000..0ffa122 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/JD/TaobaoFragment.java @@ -0,0 +1,171 @@ +package com.android.jingdong.ui.JD; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.jingdong.model.JD; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.activity.DetailActivity; +import com.android.jingdong.adaptor.TaobaoLeftAdapter; +import com.android.jingdong.adaptor.TaobaoRightAdapter; +import com.android.jingdong.data.DataServer; +import com.android.jingdong.utils.Tips; + +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class TaobaoFragment extends Fragment { + + private TaobaoViewModel taobaoViewModel; + + // 乐器页面左边列表已选择的Position + private int leftSelectPosition = 0; + + @BindView(R.id.snackLeftRecyclerView) + RecyclerView leftRecyclerview; + + @BindView(R.id.snackRightRecyclerView) + RecyclerView rightRecyclerView; + + // 右边适配器 + private TaobaoRightAdapter rightAdapter; + + public static TaobaoFragment newInstance() { + return new TaobaoFragment(); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + taobaoViewModel = ViewModelProviders.of(this).get(TaobaoViewModel.class); + View root = inflater.inflate(R.layout.fragment_snack, container, false); + // 绑定资源 + ButterKnife.bind(this, root); + return root; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + leftRecyclerview.setLayoutManager(new LinearLayoutManager(getActivity())); + rightRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + + initLeftAdapter(); + initRightAdapter(); + } + + /** + * 初始化左边适配器 + */ + @SuppressLint("ResourceAsColor") + private void initLeftAdapter() { + // 实例化左边适配器对象 + TaobaoLeftAdapter leftAdapter = new TaobaoLeftAdapter(DataServer.getSnackOrderList()); + // 设置动画效果 + leftAdapter.setAnimationEnable(true); + leftAdapter.setAnimationFirstOnly(false); + leftAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInLeft); + + // 触发点击按钮 + leftAdapter.setOnItemClickListener((adapter, view, position) -> { + if (position != leftSelectPosition) { + String item = (String) adapter.getItem(position); + + // 原本选中的item变成未选中颜色 + Objects.requireNonNull(adapter.getViewByPosition(leftSelectPosition, R.id.snackLeftType)).setBackgroundResource(R.color.colorContent); + // 当前item变成选中颜色 + Objects.requireNonNull(adapter.getViewByPosition(position, R.id.snackLeftType)).setBackgroundResource(R.color.colorBgWhite); + leftSelectPosition = position; + + // 刷新右边列表 +// rightAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom); + rightAdapter.setAnimationEnable(false); + switch (position) { + case 1: + rightAdapter.setNewInstance(DataServer.getGuangxiList()); + break; + case 2: + rightAdapter.setNewInstance(DataServer.getGuangzhouList()); + break; + case 3: +// rightAdapter.setNewInstance(DataServer.getBeijingList()); + break; + case 4: +// rightAdapter.setNewInstance(DataServer.getChongqingList()); + break; + default: + rightAdapter.setNewInstance(DataServer.getFujianList()); + break; + } + } + }); + + // 设置左边列表适配器 + leftRecyclerview.setAdapter(leftAdapter); + } + + /** + * 初始化右边适配器 + */ + public void initRightAdapter() { + // 实例化右边适配器对象 + rightAdapter = new TaobaoRightAdapter(DataServer.getFujianList()); + // 设置动画效果 + rightAdapter.setAnimationEnable(true); +// rightAdapter.setAnimationFirstOnly(false); + rightAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInRight); + // 设置尾部 + rightAdapter.addFooterView(getFooterView()); + + // 点击item事件 + rightAdapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + JD JD = (JD) adapter.getItem(position); + DetailActivity.actionStart(getContext(), JD); + } + }); + + // 左边列表加入购物车点击事件 + rightAdapter.addChildClickViewIds(R.id.snackRightAddBtn); + rightAdapter.setOnItemChildClickListener((adapter, view, position) -> { + JD JD = (JD) adapter.getItem(position); + if (view.getId() == R.id.snackRightAddBtn) { + if (!MyApplication.getCartTaobaos().contains(JD)) { + // 添加到购物车 + JD.setCount(1); + MyApplication.getCartTaobaos().add(JD); + Tips.show("已添加" + JD.getName() + "到购物车"); + } else { + Tips.show("已在购物车中,不能重复添加"); + } + } + }); + + // 设置右边列表适配器 + rightRecyclerView.setAdapter(rightAdapter); + } + + /** + * 乐器页面右边RecyclerView尾部View + */ + private View getFooterView() { + return getLayoutInflater().inflate(R.layout.footer_no_item, rightRecyclerView, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/JD/TaobaoViewModel.java b/app/src/main/java/com/android/jingdong/ui/JD/TaobaoViewModel.java new file mode 100644 index 0000000..0f4f1c0 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/JD/TaobaoViewModel.java @@ -0,0 +1,19 @@ +package com.android.jingdong.ui.JD; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.ViewModel; + +public class TaobaoViewModel extends ViewModel { + + private MediatorLiveData mText; + + public TaobaoViewModel() { + mText = new MediatorLiveData<>(); + mText.setValue("点单页面"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/home/HomeFragment.java b/app/src/main/java/com/android/jingdong/ui/home/HomeFragment.java new file mode 100644 index 0000000..e9ded48 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/home/HomeFragment.java @@ -0,0 +1,88 @@ +package com.android.jingdong.ui.home; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.android.jingdong.R; +import com.android.jingdong.activity.DetailActivity; +import com.android.jingdong.adaptor.HomeAdapter; +import com.android.jingdong.animator.MyAnimation3; +import com.android.jingdong.data.DataServer; +import com.android.jingdong.model.JD; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class HomeFragment extends Fragment { + + private HomeViewModel homeViewModel; + + @BindView(R.id.homeRecyclerView) + RecyclerView homeRecyclerView; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + homeViewModel = + ViewModelProviders.of(this).get(HomeViewModel.class); + View root = inflater.inflate(R.layout.fragment_home, container, false); + // 绑定资源 + ButterKnife.bind(this, root); + return root; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // 首页瀑布流列表 + homeRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)); + + initHomeAdapter(); + } + + private void initHomeAdapter() { + // 实例化购物车列表适配器对象 + HomeAdapter adapter = new HomeAdapter(DataServer.getHomeList()); + // 设置动画效果 + adapter.setAnimationEnable(true); +// adapter.setAnimationFirstOnly(false); +// adapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom); + adapter.setAdapterAnimation(new MyAnimation3()); + // 设置头部 + adapter.setHeaderView(getHeadView(), 1); + // 设置尾部 + adapter.setFooterView(getFooterView(), 1); + + // 点击事件监听器 + adapter.setOnItemClickListener((adapter1, view, position) -> { + JD JD = (JD) adapter1.getItem(position); + DetailActivity.actionStart(getContext(), JD); + }); + + // 设置适配器 + homeRecyclerView.setAdapter(adapter); + } + + /** + * 首页RecyclerView头部View + */ + private View getHeadView() { + return getLayoutInflater().inflate(R.layout.head_home_image, homeRecyclerView, false); + } + + /** + * 首页RecyclerView尾部View + */ + private View getFooterView() { + return getLayoutInflater().inflate(R.layout.footer_no_item, homeRecyclerView, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/home/HomeViewModel.java b/app/src/main/java/com/android/jingdong/ui/home/HomeViewModel.java new file mode 100644 index 0000000..8d24afd --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/home/HomeViewModel.java @@ -0,0 +1,19 @@ +package com.android.jingdong.ui.home; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class HomeViewModel extends ViewModel { + + private MutableLiveData mText; + + public HomeViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("首页页面"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/my/MyFragment.java b/app/src/main/java/com/android/jingdong/ui/my/MyFragment.java new file mode 100644 index 0000000..e70f15c --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/my/MyFragment.java @@ -0,0 +1,196 @@ +package com.android.jingdong.ui.my; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; + +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.activity.LoginActivity; +import com.android.jingdong.activity.OrderActivity; +import com.android.jingdong.dao.UserDao; +import com.android.jingdong.model.User; +import com.android.jingdong.utils.Tips; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import de.hdodenhof.circleimageview.CircleImageView; + +public class MyFragment extends Fragment { + + private MyViewModel myViewModel; + + @BindView(R.id.myUserHead) + CircleImageView image; + + @BindView(R.id.constraintLayout) + ConstraintLayout constraintLayout; + + @BindView(R.id.myUserNickName) + TextView nickname; + + @BindView(R.id.myUserName) + TextView username; + + @BindView(R.id.myModifyView) + LinearLayout modifyView; + + @BindView(R.id.myGeneralView) + LinearLayout generalView; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + myViewModel = + ViewModelProviders.of(this).get(MyViewModel.class); + View root = inflater.inflate(R.layout.fragment_my, container, false); + + // 绑定资源 + ButterKnife.bind(this, root); + return root; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + initView(); + } + + @Override + public void onResume() { + super.onResume(); + initView(); + } + + @SuppressLint("SetTextI18n") + private void initView() { + if (MyApplication.isLogin()) { + User user = MyApplication.getUser(); + image.setImageResource(user.getHeadImage()); + nickname.setText(user.getNickname()); + username.setText("账号: " + user.getUsername()); + } + } + + @OnClick(R.id.myUserHead) + void clickImage() { + if (MyApplication.isLogin()) { + Tips.show("已登录"); + } else { + LoginActivity.actionStart(getActivity()); + } + } + + @OnClick(R.id.constraintLayout) + void clickcslayout() { + if (MyApplication.isLogin()) { + Tips.show("已登录"); + } else { + LoginActivity.actionStart(getActivity()); + } + } + + /** + * 点击我的订单 + */ + @OnClick(R.id.myOrderView) + void clickOrder() { + if (MyApplication.isLogin()) { + OrderActivity.actionStart(getContext()); + } else { + Tips.show("请先登录"); + } + } + + @OnClick(R.id.myModifyText) + void clickShowModify() { + if (modifyView.getVisibility() == View.GONE) { + modifyView.setVisibility(View.VISIBLE); + } else { + modifyView.setVisibility(View.GONE); + } + } + + @OnClick(R.id.myGeneralText) + void clickShowGeneral() { + if (generalView.getVisibility() == View.GONE) { + generalView.setVisibility(View.VISIBLE); + } else { + generalView.setVisibility(View.GONE); + } + } + + @OnClick(R.id.myModifyBtn) + void clickModifySubmit() { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("提示") + .setMessage("是否保存地址信息") + .setPositiveButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + modifyView.setVisibility(View.GONE); + } + }) + .create() + .show(); + } + + @OnClick(R.id.myGeneralBtn) + void clickGeneralSubmit() { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("提示") + .setMessage("是否保存通用设置") + .setPositiveButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + } + }) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + generalView.setVisibility(View.GONE); + } + }) + .create() + .show(); + } + + /** + * 点击退出登录 + */ + @OnClick(R.id.logoutBtn) + void clickLogout() { + if (MyApplication.isLogin()) { + // 清除持久化数据 + UserDao.removeUserAndLoginStatus(); + // 清除全局数据 + MyApplication.isLogin(false); + MyApplication.setUser(null); + nickname.setText("未登录"); + username.setText(""); + image.setImageResource(R.mipmap.logo); + } else { + Tips.show("还没有登录,请先登录"); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/my/MyViewModel.java b/app/src/main/java/com/android/jingdong/ui/my/MyViewModel.java new file mode 100644 index 0000000..da4ea56 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/my/MyViewModel.java @@ -0,0 +1,19 @@ +package com.android.jingdong.ui.my; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class MyViewModel extends ViewModel { + + private MutableLiveData mText; + + public MyViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("我的页面"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/place/PlaceFragment.java b/app/src/main/java/com/android/jingdong/ui/place/PlaceFragment.java new file mode 100644 index 0000000..26d972c --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/place/PlaceFragment.java @@ -0,0 +1,248 @@ +package com.android.jingdong.ui.place; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProviders; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.jingdong.model.JD; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.listener.OnItemClickListener; +import com.android.jingdong.MyApplication; +import com.android.jingdong.R; +import com.android.jingdong.activity.DetailActivity; +import com.android.jingdong.adaptor.PlaceOrderAdapter; +import com.android.jingdong.dao.OrderDao; +import com.android.jingdong.model.Order; +import com.android.jingdong.utils.Tips; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class PlaceFragment extends Fragment { + + private PlaceViewModel placeViewModel; + + @BindView(R.id.placeRecyclerView) + RecyclerView orderRecyclerView; + + @BindView(R.id.placeBuyBtn) + Button buyButton; + + @BindView(R.id.placeMoney) + TextView placeMoney; + + PlaceOrderAdapter orderAdapter; + + public View onCreateView(@NonNull LayoutInflater inflater, + ViewGroup container, Bundle savedInstanceState) { + placeViewModel = + ViewModelProviders.of(this).get(PlaceViewModel.class); + View root = inflater.inflate(R.layout.fragment_place, container, false); + // 绑定资源 + ButterKnife.bind(this, root); +// final TextView textView = root.findViewById(R.id.text_notifications); +// notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer() { +// @Override +// public void onChanged(@Nullable String s) { +// textView.setText(s); +// } +// }); + return root; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + orderRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + initOrderAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + // 每次页面显示都计算合计金额 + calcTotalMoney(); + } + + /** + * 初始化购物车列表适配器 + */ + private void initOrderAdapter() { + // 实例化购物车列表适配器对象 + orderAdapter = new PlaceOrderAdapter(MyApplication.getCartTaobaos()); + + // 设置空布局 + orderAdapter.setEmptyView(getEmptyView()); + + // 设置动画效果 + orderAdapter.setAnimationEnable(true); +// orderAdapter.setAnimationFirstOnly(false); + orderAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.ScaleIn); + + // 点击item事件触发 + orderAdapter.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) { + JD JD = (JD) adapter.getItem(position); + DetailActivity.actionStart(getContext(), JD); + } + }); + + // 注册item内子控件id + orderAdapter.addChildClickViewIds(R.id.orderLessLabel, R.id.orderAddLabel); + // 子控件点击监听 + orderAdapter.setOnItemChildClickListener((adapter, view, position) -> { + JD JD = (JD) adapter.getItem(position); + switch (view.getId()) { + case R.id.orderLessLabel: + // 点击减少数量 + if (JD.getCount() == 1) { + MyApplication.getCartTaobaos().remove(position); + } else { + MyApplication.getCartTaobaos().get(position).setCount(JD.getCount() - 1); + } + + adapter.notifyDataSetChanged(); + break; + case R.id.orderAddLabel: + // 点击添加数量 + MyApplication.getCartTaobaos().get(position).setCount(JD.getCount() + 1); + adapter.notifyDataSetChanged(); + break; + default: + break; + } + calcTotalMoney(); + }); + + // 设置适配器 + orderRecyclerView.setAdapter(orderAdapter); + } + + /** + * 点击下单按钮事件触发器 + */ + @OnClick(R.id.placeBuyBtn) + void initClick() { + if (MyApplication.getCartTaobaos().isEmpty()) { + Tips.show("购物车是空的啦!!!"); + } else { + if (MyApplication.isLogin()) { + // 显示Dialog + showDialog(); + } else { + Tips.show("请先登录"); + } + } + } + + /** + * 显示下单备注提示框 + */ + @SuppressLint("InflateParams") + public void showDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = requireActivity().getLayoutInflater(); + + builder.setView(inflater.inflate(R.layout.dialog_view, null)) + .setTitle("备注") + .setPositiveButton("下单", (dialog, which) -> { + // 持久化订单数据 + saveOrder(); + + // 清空购物车数据 + MyApplication.getCartTaobaos().removeAll(MyApplication.getCartTaobaos()); + // 通知适配器数据变化 + orderAdapter.notifyDataSetChanged(); + // 刷新总金额 + calcTotalMoney(); + + Tips.show("下单成功"); + }) + .create() + .show(); + } + + /** + * 持久化订单数据 + */ + public void saveOrder() { + List orders = new ArrayList<>(); + // 购物车数据产生订单 + for (JD JD : MyApplication.getCartTaobaos()) { + Order order = new Order(JD); + order.setUsername(MyApplication.getUser().getUsername()); + orders.add(order); + } + + OrderDao.saveOrder(orders); + } + + /** + * 点击垃圾桶事件触发器 + */ + @OnClick(R.id.deleteOrder) + void deleteOrder() { + if (MyApplication.getCartTaobaos().isEmpty()) { + Tips.show("购物车是空的"); + } else { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("提示") + .setMessage("是否清空购物车?") + .setPositiveButton("确定", (dialog, which) -> { + // 清空购物车数据 + MyApplication.getCartTaobaos().removeAll(MyApplication.getCartTaobaos()); + // 通知适配器数据变化 + orderAdapter.notifyDataSetChanged(); + // 刷新总金额 + calcTotalMoney(); + + Tips.show("已清空购物车"); + }) + .create() + .show(); + } + } + + // 计算合计金额 + @SuppressLint("SetTextI18n") + private void calcTotalMoney() { + BigDecimal totalMoney = BigDecimal.valueOf(0); + + // 遍历计算总金额(解决舍入误差) + if (!MyApplication.getCartTaobaos().isEmpty()) { + for (JD JD : MyApplication.getCartTaobaos()) { + // 乐器单价 × 乐器数量 + BigDecimal tmp = BigDecimal.valueOf(JD.getPrice()).multiply(BigDecimal.valueOf(JD.getCount())); + totalMoney = totalMoney.add(tmp); + } + } + + placeMoney.setText("¥" + totalMoney.doubleValue()); + } + + /** + * 下单页面购物车空布局 + */ + private View getEmptyView() { + return getLayoutInflater().inflate(R.layout.empty_cart_view, orderRecyclerView, false); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/ui/place/PlaceViewModel.java b/app/src/main/java/com/android/jingdong/ui/place/PlaceViewModel.java new file mode 100644 index 0000000..9cce701 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/ui/place/PlaceViewModel.java @@ -0,0 +1,19 @@ +package com.android.jingdong.ui.place; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +public class PlaceViewModel extends ViewModel { + + private MutableLiveData mText; + + public PlaceViewModel() { + mText = new MutableLiveData<>(); + mText.setValue("下单页面"); + } + + public LiveData getText() { + return mText; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/android/jingdong/utils/Tips.java b/app/src/main/java/com/android/jingdong/utils/Tips.java new file mode 100644 index 0000000..1975bb2 --- /dev/null +++ b/app/src/main/java/com/android/jingdong/utils/Tips.java @@ -0,0 +1,84 @@ +package com.android.jingdong.utils; + +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.RoundRectShape; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; +import android.widget.Toast; + +public class Tips { + + /** + * 显示Toast + * + * @param message 显示的文本消息 + */ + public static void show(String message) { + show(message, Toast.LENGTH_SHORT); + } + + /** + * 显示Toast + * + * @param message 显示的文本消息 + * @param duration 显示时间长度 + */ + public static void show(String message, int duration) { + Toast toast = new Toast(Utils.getContext()); + toast.setDuration(duration); + toast.setGravity(Gravity.CENTER, 0, 0); + toast.setView(createToastView(message)); + toast.show(); + } + + /** + * 创建Toast自定义View + * + * @param message 显示的文本消息 + * @return 自定义View + */ + private static View createToastView(String message) { + // 构建圆角矩形背景 + float radius = dp2px(6); + RoundRectShape shape = new RoundRectShape(new float[]{radius, radius, radius, radius, radius, radius, radius, radius}, null, null); + ShapeDrawable drawable = new ShapeDrawable(shape); + drawable.getPaint().setColor(Color.argb(225, 240, 240, 240)); + drawable.getPaint().setStyle(Paint.Style.FILL); + drawable.getPaint().setAntiAlias(true); + drawable.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG); + + // 创建View + FrameLayout layout = new FrameLayout(Utils.getContext()); + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + layout.setLayoutParams(layoutParams); + layout.setPadding(dp2px(16), dp2px(12), dp2px(16), dp2px(12)); + layout.setBackground(drawable); + + TextView textView = new TextView(Utils.getContext()); + textView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT)); + textView.setTextSize(15); + textView.setText(message); + textView.setLineSpacing(dp2px(4), 1f); + textView.setTextColor(Color.BLACK); + + layout.addView(textView); + + return layout; + } + + /** + * dp转px + * + * @param dp dp的值 + * @return 转换后的px + */ + private static int dp2px(float dp) { + final float scale = Utils.getContext().getResources().getDisplayMetrics().density; + return (int) (dp * scale + 0.5f); + } +} diff --git a/app/src/main/java/com/android/jingdong/utils/Utils.java b/app/src/main/java/com/android/jingdong/utils/Utils.java new file mode 100644 index 0000000..9bc0c8e --- /dev/null +++ b/app/src/main/java/com/android/jingdong/utils/Utils.java @@ -0,0 +1,35 @@ +package com.android.jingdong.utils; + +import android.annotation.SuppressLint; +import android.content.Context; + +public class Utils { + + @SuppressLint("StaticFieldLeak") + private static Context context; + + private Utils() { + throw new UnsupportedOperationException("我是需要实例化的啦!!!"); + } + + /** + * 初始化工具类 + * + * @param context 上下文 + */ + public static void init(Context context) { + Utils.context = context.getApplicationContext(); + } + + /** + * 获取应用的ApplicationContext + * + * @return ApplicationContext + */ + public static Context getContext() { + if (context != null) { + return context; + } + throw new NullPointerException("上下文为空啊!!!"); + } +} 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/back_bg.xml b/app/src/main/res/drawable/back_bg.xml new file mode 100644 index 0000000..81b48d5 --- /dev/null +++ b/app/src/main/res/drawable/back_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/banner.png b/app/src/main/res/drawable/banner.png new file mode 100644 index 0000000..f9aac2a Binary files /dev/null and b/app/src/main/res/drawable/banner.png differ diff --git a/app/src/main/res/drawable/detail_info.xml b/app/src/main/res/drawable/detail_info.xml new file mode 100644 index 0000000..60b91c3 --- /dev/null +++ b/app/src/main/res/drawable/detail_info.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_baseline_assignment_24dp.xml b/app/src/main/res/drawable/ic_baseline_assignment_24dp.xml new file mode 100644 index 0000000..444ccdc --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_assignment_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_assignment_turned_in_24dp.xml b/app/src/main/res/drawable/ic_baseline_assignment_turned_in_24dp.xml new file mode 100644 index 0000000..5d5680e --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_assignment_turned_in_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_delete_24dp.xml b/app/src/main/res/drawable/ic_baseline_delete_24dp.xml new file mode 100644 index 0000000..3c4030b --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_delete_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_favorite_24dp.xml b/app/src/main/res/drawable/ic_baseline_favorite_24dp.xml new file mode 100644 index 0000000..fca0971 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_favorite_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_favorite_border_24dp.xml b/app/src/main/res/drawable/ic_baseline_favorite_border_24dp.xml new file mode 100644 index 0000000..3edfe1d --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_favorite_border_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_navigate_before_24dp.xml b/app/src/main/res/drawable/ic_baseline_navigate_before_24dp.xml new file mode 100644 index 0000000..f0d71e1 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_navigate_before_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_question_answer_24dp.xml b/app/src/main/res/drawable/ic_baseline_question_answer_24dp.xml new file mode 100644 index 0000000..4bc2544 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_question_answer_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_baseline_report_24dp.xml b/app/src/main/res/drawable/ic_baseline_report_24dp.xml new file mode 100644 index 0000000..811e67b --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_report_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_cart_black_24dp.xml b/app/src/main/res/drawable/ic_cart_black_24dp.xml new file mode 100644 index 0000000..cf0dcc8 --- /dev/null +++ b/app/src/main/res/drawable/ic_cart_black_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_di1.xml b/app/src/main/res/drawable/ic_di1.xml new file mode 100644 index 0000000..4dc8422 --- /dev/null +++ b/app/src/main/res/drawable/ic_di1.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_di2.xml b/app/src/main/res/drawable/ic_di2.xml new file mode 100644 index 0000000..37050de --- /dev/null +++ b/app/src/main/res/drawable/ic_di2.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_di3.xml b/app/src/main/res/drawable/ic_di3.xml new file mode 100644 index 0000000..0c00d93 --- /dev/null +++ b/app/src/main/res/drawable/ic_di3.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_di4.xml b/app/src/main/res/drawable/ic_di4.xml new file mode 100644 index 0000000..13aef7f --- /dev/null +++ b/app/src/main/res/drawable/ic_di4.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/src/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000..70fb291 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ + + + 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/ic_my_black_24dp.xml b/app/src/main/res/drawable/ic_my_black_24dp.xml new file mode 100644 index 0000000..6bdced2 --- /dev/null +++ b/app/src/main/res/drawable/ic_my_black_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml new file mode 100644 index 0000000..affc7ba --- /dev/null +++ b/app/src/main/res/drawable/ic_search_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_sharp_monetization_on_24dp.xml b/app/src/main/res/drawable/ic_sharp_monetization_on_24dp.xml new file mode 100644 index 0000000..4b5b299 --- /dev/null +++ b/app/src/main/res/drawable/ic_sharp_monetization_on_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_snack_black_24dp.xml b/app/src/main/res/drawable/ic_snack_black_24dp.xml new file mode 100644 index 0000000..4797566 --- /dev/null +++ b/app/src/main/res/drawable/ic_snack_black_24dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/jd.png b/app/src/main/res/drawable/jd.png new file mode 100644 index 0000000..034d7ce Binary files /dev/null and b/app/src/main/res/drawable/jd.png differ diff --git a/app/src/main/res/drawable/jingdong.png b/app/src/main/res/drawable/jingdong.png new file mode 100644 index 0000000..097377b Binary files /dev/null and b/app/src/main/res/drawable/jingdong.png differ diff --git a/app/src/main/res/drawable/my_general_setting.xml b/app/src/main/res/drawable/my_general_setting.xml new file mode 100644 index 0000000..20218d9 --- /dev/null +++ b/app/src/main/res/drawable/my_general_setting.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/one4.png b/app/src/main/res/drawable/one4.png new file mode 100644 index 0000000..84cdbdb Binary files /dev/null and b/app/src/main/res/drawable/one4.png differ diff --git a/app/src/main/res/drawable/place_buy_btn.xml b/app/src/main/res/drawable/place_buy_btn.xml new file mode 100644 index 0000000..5be6557 --- /dev/null +++ b/app/src/main/res/drawable/place_buy_btn.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/place_order_count_btn.xml b/app/src/main/res/drawable/place_order_count_btn.xml new file mode 100644 index 0000000..047dcd1 --- /dev/null +++ b/app/src/main/res/drawable/place_order_count_btn.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/place_order_item.xml b/app/src/main/res/drawable/place_order_item.xml new file mode 100644 index 0000000..9b310da --- /dev/null +++ b/app/src/main/res/drawable/place_order_item.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/radius_content.xml b/app/src/main/res/drawable/radius_content.xml new file mode 100644 index 0000000..0d44743 --- /dev/null +++ b/app/src/main/res/drawable/radius_content.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/snack_right_item.xml b/app/src/main/res/drawable/snack_right_item.xml new file mode 100644 index 0000000..8ca2977 --- /dev/null +++ b/app/src/main/res/drawable/snack_right_item.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml new file mode 100644 index 0000000..1d6ba0f --- /dev/null +++ b/app/src/main/res/layout/activity_detail.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +