plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.example.unbookstore"
compileSdk = 34
defaultConfig {
applicationId = "com.example.unbookstore"
minSdk = 24
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = 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 {
// AndroidX Core
implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
// GridLayout support
implementation(libs.gridlayout)
// Image loading library
implementation(libs.glide)
annotationProcessor("com.github.bumptech.glide:compiler:4.16.0")
// Lifecycle components
implementation(libs.lifecycle.runtime.ktx)
implementation(libs.lifecycle.viewmodel.ktx)
// Testing
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
} fix it and give me right code to run if any changes you need then proccess and do it
Your build.gradle.kts file looks mostly good, but there's one inconsistency with the Glide compiler dependency. Let's fix that to use the version catalog approach consistently:
plugins {
alias(libs.plugins.android.application)
}
android {
namespace = "com.example.unbookstore"
compileSdk = 34
defaultConfig {
applicationId = "com.example.unbookstore"
minSdk = 24
targetSdk = 33
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = 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 {
// AndroidX Core
implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
// GridLayout support
implementation(libs.gridlayout)
// Image loading library
implementation(libs.glide)
annotationProcessor(libs.glide.compiler) // Changed to use version catalog
// Lifecycle components
implementation(libs.lifecycle.runtime.ktx)
implementation(libs.lifecycle.viewmodel.ktx)
// Testing
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}You need to make sure your version catalog file (located at gradle/libs.versions.toml) includes all the necessary dependencies. Here's what it should look like:
[versions]
core-ktx = "1.12.0"
appcompat = "1.6.1"
material = "1.11.0"
activity = "1.8.2"
constraintlayout = "2.1.4"
gridlayout = "1.0.0"
glide = "4.16.0"
lifecycle = "2.7.0"
junit = "4.13.2"
ext-junit = "1.1.5"
espresso = "3.5.1"
[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
gridlayout = { group = "androidx.gridlayout", name = "gridlayout", version.ref = "gridlayout" }
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
glide-compiler = { group = "com.github.bumptech.glide", name = "compiler", version.ref = "glide" }
lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "ext-junit" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" }
[plugins]
android-application = { id = "com.android.application", version = "8.2.0" } # Update this version to match your Android Gradle Plugin versionUpdate the version catalog file:
gradle/libs.versions.toml in your projectUpdate your build.gradle.kts file:
Sync your project:
Clean and rebuild:
Run your app:
These changes ensure that all your dependencies are consistently using the version catalog approach, which makes dependency management cleaner and more maintainable.
I'll guide you step-by-step to implement both the Register and Login screens for your UN Book Store app. Let's start with creating the necessary files and implementing each screen one by one.
First, let's create the layout file for the Register screen:
res/layout folder in your projectactivity_register.xml<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp"
tools:context=".RegisterActivity">
<ImageButton
android:id="@+id/backButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Back"
android:src="@drawable/ic_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@android:color/black" />
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Register"
android:textColor="@android:color/black"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/subtitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Please fill your details to signup."
android:textColor="@android:color/darker_gray"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTextView" />
<EditText
android:id="@+id/usernameEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/edit_text_background"
android:hint="Username"
android:inputType="text"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleTextView" />
<EditText
android:id="@+id/emailEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/edit_text_background"
android:hint="Email"
android:inputType="textEmailAddress"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/usernameEditText" />
<EditText
android:id="@+id/passwordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/edit_text_background"
android:hint="Password"
android:inputType="textPassword"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/emailEditText" />
<EditText
android:id="@+id/confirmPasswordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/edit_text_background"
android:hint="Confirm Password"
android:inputType="textPassword"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/passwordEditText" />
<Button
android:id="@+id/registerButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:background="@drawable/black_button_background"
android:padding="16dp"
android:text="Register"
android:textAllCaps="false"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/confirmPasswordEditText" />
<TextView
android:id="@+id/signInTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="Already a member? SignIn"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>res/drawable folderedit_text_background.xml<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#EEEEEE" />
<corners android:radius="4dp" />
</shape>res/drawable folderic_backjava folderRegisterActivitypackage com.example.unbookstore;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class RegisterActivity extends AppCompatActivity {
private EditText usernameEditText, emailEditText, passwordEditText, confirmPasswordEditText;
private Button registerButton;
private TextView signInTextView;
private ImageButton backButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
// Initialize views
usernameEditText = findViewById(R.id.usernameEditText);
emailEditText = findViewById(R.id.emailEditText);
passwordEditText = findViewById(R.id.passwordEditText);
confirmPasswordEditText = findViewById(R.id.confirmPasswordEditText);
registerButton = findViewById(R.id.registerButton);
signInTextView = findViewById(R.id.signInTextView);
backButton = findViewById(R.id.backButton);
// Set up click listeners
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Validate input fields
if (validateInputs()) {
// Perform registration
registerUser();
}
}
});
signInTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Navigate to login screen
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
});
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Go back to previous screen
onBackPressed();
}
});
}
private boolean validateInputs() {
String username = usernameEditText.getText().toString().trim();
String email = emailEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
String confirmPassword = confirmPasswordEditText.getText().toString().trim();
// Check if fields are empty
if (username.isEmpty()) {
usernameEditText.setError("Username is required");
return false;
}
if (email.isEmpty()) {
emailEditText.setError("Email is required");
return false;
}
if (password.isEmpty()) {
passwordEditText.setError("Password is required");
return false;
}
if (confirmPassword.isEmpty()) {
confirmPasswordEditText.setError("Confirm password is required");
return false;
}
// Check if passwords match
if (!password.equals(confirmPassword)) {
confirmPasswordEditText.setError("Passwords do not match");
return false;
}
return true;
}
private void registerUser() {
// In a real app, you would implement actual registration logic here
// For this example, we'll just show a success message and navigate to the login screen
Toast.makeText(this, "Registration successful!", Toast.LENGTH_SHORT).show();
// Navigate to login screen
Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}res/layout folderactivity_login.xml<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp"
tools:context=".LoginActivity">
<ImageButton
android:id="@+id/backButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Back"
android:src="@drawable/ic_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@android:color/black" />
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Started"
android:textColor="@android:color/black"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/subtitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Please fill your details to login."
android:textColor="@android:color/darker_gray"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTextView" />
<EditText
android:id="@+id/usernameEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:background="@drawable/edit_text_background"
android:hint="Username/email"
android:inputType="text"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/subtitleTextView" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/passwordLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/edit_text_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/usernameEditText">
<EditText
android:id="@+id/passwordEditText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@null"
android:hint="Password"
android:inputType="textPassword"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/passwordVisibilityToggle"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="@+id/passwordVisibilityToggle"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="Toggle password visibility"
android:src="@drawable/ic_visibility"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@android:color/darker_gray" />
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="@+id/loginButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:background="@drawable/black_button_background"
android:padding="16dp"
android:text="Get Started"
android:textAllCaps="false"
android:textColor="@android:color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/passwordLayout" />
<TextView
android:id="@+id/forgotPasswordTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="forgot password?"
android:textColor="@android:color/darker_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/loginButton" />
<TextView
android:id="@+id/registerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="32dp"
android:text="New member? Register"
android:textColor="@android:color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>res/drawable folderic_visibilityic_visibility_offjava folderLoginActivitypackage com.example.unbookstore;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class LoginActivity extends AppCompatActivity {
private EditText usernameEditText, passwordEditText;
private Button loginButton;
private TextView forgotPasswordTextView, registerTextView;
private ImageButton backButton, passwordVisibilityToggle;
private boolean isPasswordVisible = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Initialize views
usernameEditText = findViewById(R.id.usernameEditText);
passwordEditText = findViewById(R.id.passwordEditText);
loginButton = findViewById(R.id.loginButton);
forgotPasswordTextView = findViewById(R.id.forgotPasswordTextView);
registerTextView = findViewById(R.id.registerTextView);
backButton = findViewById(R.id.backButton);
passwordVisibilityToggle = findViewById(R.id.passwordVisibilityToggle);
// Set up click listeners
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Validate input fields
if (validateInputs()) {
// Perform login
loginUser();
}
}
});
forgotPasswordTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Handle forgot password
Toast.makeText(LoginActivity.this, "Forgot password functionality will be implemented", Toast.LENGTH_SHORT).show();
}
});
registerTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Navigate to register screen
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivity(intent);
finish();
}
});
backButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Go back to previous screen
onBackPressed();
}
});
passwordVisibilityToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
togglePasswordVisibility();
}
});
}
private boolean validateInputs() {
String username = usernameEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();
// Check if fields are empty
if (username.isEmpty()) {
usernameEditText.setError("Username/email is required");
return false;
}
if (password.isEmpty()) {
passwordEditText.setError("Password is required");
return false;
}
return true;
}
private void loginUser() {
// In a real app, you would implement actual login logic here
// For this example, we'll just show a success message and navigate to the main screen
Toast.makeText(this, "Login successful!", Toast.LENGTH_SHORT).show();
// Navigate to main screen
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
private void togglePasswordVisibility() {
isPasswordVisible = !isPasswordVisible;
if (isPasswordVisible) {
// Show password
passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
passwordVisibilityToggle.setImageResource(R.drawable.ic_visibility_off);
} else {
// Hide password
passwordEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordVisibilityToggle.setImageResource(R.drawable.ic_visibility);
}
// Move cursor to the end of the text
passwordEditText.setSelection(passwordEditText.getText().length());
}
}Update your WelcomeActivity.java file to navigate to the LoginActivity when "Get Started" is clicked and to RegisterActivity when "Register" is clicked:
package com.example.unbookstore;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class WelcomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
// Hide the action bar if it exists
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
// Get Started button click listener
Button getStartedButton = findViewById(R.id.getStartedButton);
getStartedButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Navigate to the login activity
Intent loginIntent = new Intent(WelcomeActivity.this, LoginActivity.class);
startActivity(loginIntent);
}
});
// Register text click listener
TextView registerButton = findViewById(R.id.registerButton);
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Navigate to the registration activity
Intent registerIntent = new Intent(WelcomeActivity.this, RegisterActivity.class);
startActivity(registerIntent);
}
});
}
}Update your AndroidManifest.xml to include the new activities:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.unbookstore">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.UnBookStore">
<activity
android:name=".SplashActivity"
android:exported="true"
android:theme="@style/Theme.UnBookStore.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".WelcomeActivity"
android:exported="false"
android:theme="@style/Theme.UnBookStore.NoActionBar" />
<activity
android:name=".LoginActivity"
android:exported="false"
android:theme="@style/Theme.UnBookStore.NoActionBar" />
<activity
android:name=".RegisterActivity"
android:exported="false"
android:theme="@style/Theme.UnBookStore.NoActionBar" />
<activity
android:name=".MainActivity"
android:exported="false" />
</application>
</manifest>The app now has a complete user authentication flow with:
All screens are designed according to the mockups you provided, with proper navigation between them.