Animations and Interpolations in Android
Introduction
Android provides a robust animation framework that allows developers to create engaging user interfaces by animating UI elements. Animations in Android range from simple transitions (like fading or moving a view) to complex properties manipulation. Interpolators define the rate of change of an animation, controlling whether an animation accelerates, decelerates, or moves at a constant rate over time.
Main Attributes
android:duration: Sets the total time (in milliseconds) the animation should run.
android:fromAlpha / android:toAlpha: Defines starting and ending transparency levels (0.0 to 1.0).
android:fromXDelta / android:toXDelta: Defines horizontal movement values.
android:pivotX / android:pivotY: Sets the center point for scaling or rotation.
android:interpolator: Specifies the interpolator (e.g., @android:anim/accelerate_interpolator).
XML Code
res/anim/fade_in.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<alpha
android:duration="1000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Animated Text"
android:textSize="24sp" />
<Button
android:id="@+id/btnAnimate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Start Animation" />
</LinearLayout>
JAVA Code
package com.example.animationdemo;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
Button btnAnimate = findViewById(R.id.btnAnimate);
btnAnimate.setOnClickListener(v -> {
Animation fadeIn = AnimationUtils.loadAnimation(MainActivity.this, R.anim.fade_in);
textView.startAnimation(fadeIn);
});
}
}
Sample Output
When the user taps the Start Animation button, the text label gradually fades into view over 1 second with a smooth acceleration and deceleration curve.
Drawing Graphics using Canvas and Paint Classes
Introduction
In Android, 2D custom graphics are drawn by extending the View class and overriding its onDraw() method. The Canvas class acts as the virtual surface onto which shapes, text, and bitmaps are drawn, while the Paint class defines the style, color, font, and stroke properties used during drawing.
Main Attributes
Paint.setColor(int color): Sets the primary drawing color.
Paint.setStyle(Paint.Style style): Sets whether shapes are filled (FILL), outlined (STROKE), or both (FILL_AND_STROKE).
Paint.setStrokeWidth(float width): Configures line or border thickness.
Paint.setAntiAlias(boolean aa): Smooths edge pixels for cleaner rendering.
Canvas.drawCircle(...) / Canvas.drawRect(...): Renders geometry on screen.
XML Code
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
JAVA Code
CustomGraphicsView.java
package com.example.graphicsdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class CustomGraphicsView extends View {
private final Paint paint;
public CustomGraphicsView(Context context) {
super(context);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300, 300, 150, paint);
paint.setColor(Color.RED);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(150, 600, 500, 900, paint);
}
}
MainActivity.java
package com.example.graphicsdemo;
import android.os.Bundle;
import android.widget.LinearLayout;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout container = findViewById(R.id.container);
CustomGraphicsView graphicsView = new CustomGraphicsView(this);
container.addView(graphicsView);
}
}
Sample Output
The screen displays a solid blue circle drawn at top-left coordinates (300,300) alongside a red rectangular border below it.
Building a Simple Image Gallery App
Introduction
An Image Gallery application displays a collection of images in a responsive grid layout. In modern Android development, RecyclerView with a GridLayoutManager is used to efficiently render image thumbnails, conserving memory by recycling view holders as the user scrolls.
Main Attributes
RecyclerView: Container view for rendering large datasets efficiently.
GridLayoutManager: Arranges child views into a multi-column grid format.
ImageView: Display element for rendering bitmap drawables.
android:numColumns / Grid span count: Sets the number of items per row.
XML Code
res/layout/item_image.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_margin="4dp"
android:scaleType="centerCrop" />
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
JAVA Code
GalleryAdapter.java
package com.example.galleryapp
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder> {
private final int[] imageResIds;
public GalleryAdapter(int[] imageResIds) {
this.imageResIds = imageResIds;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_image, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.imageView.setImageResource(imageResIds[position]);
}
@Override
public int getItemCount() {
return imageResIds.length;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView);
}
}
}
MainActivity.java
package com.example.galleryapp;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
int[] images = {
android.R.drawable.ic_menu_camera,
android.R.drawable.ic_menu_gallery,
android.R.drawable.ic_menu_compass,
android.R.drawable.ic_menu_map,
android.R.drawable.ic_menu_call,
android.R.drawable.ic_menu_agenda
};
recyclerView.setAdapter(new GalleryAdapter(images));
}
}
Sample Output
A 3-column grid of image thumbnails appears, allowing smooth vertical scrolling through the asset collection.
Spinner Widget in Android
Introduction
A Spinner provides a drop-down list interface that allows users to select a single value from a dataset. It is commonly populated using an ArrayAdapter that binds string resources or Java arrays to the view component.
Main Attributes
android:entries: References a string-array resource defined in XML.
android:prompt: Sets the title shown in the drop-down dialog header.
setOnItemSelectedListener(...): Java listener interface to handle item selection events.
XML Code
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Selected item will appear here"
android:textSize="18sp" />
</LinearLayout>
JAVA Code
package com.example.spinnerdemo;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = findViewById(R.id.spinner);
TextView tvSelected = findViewById(R.id.tvSelected);
String[] cities = {"New York", "London", "Tokyo", "Paris", "Berlin"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, cities);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
tvSelected.setText("Selected: " + cities[position]);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
tvSelected.setText("Nothing selected");
}
});
}
}
Sample Output
Tapping the Spinner opens a drop-down menu with city names. Selecting "Tokyo" updates the TextView below to read: Selected: Tokyo.
Role of Fragments in Android
Introduction
A Fragment represents a modular, reusable portion of a user interface within an Activity. Fragments have their own lifecycle, receive their own input events, and can be added or removed while the host activity is running.
Main Attributes & Role
Fragments enable adaptive layout designs across different device form factors (phones vs. tablets) by letting developers reuse UI components across multiple screen layouts.
Two Advantages
Code Reusability and Modularity: UI layouts and their corresponding logic can be encapsulated into independent fragments that are easily reused across different activities.
Adaptive UI Design: Allows multi-pane layouts on large screens (e.g., master-detail views on tablets) while displaying single-pane views on smaller smartphone screens.
XML Code
res/layout/fragment_sample.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#E0F7FA">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hello from Fragment!"
android:textSize="20sp" />
</FrameLayout>
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
JAVA Code
SampleFragment.java
package com.example.fragmentdemo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
public class SampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sample, container, false);
}
}
MainActivity.java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new SampleFragment())
.commit();
}
}
}
Sample Output
The activity dynamically embeds the fragment UI on load, rendering a light cyan screen centered with the text Hello from Fragment!.
Android SQLite API
Introduction
The Android SQLite API allows developers to store persistent structured data locally in a lightweight, relational embedded database. The framework handles database creation, schema upgrades, and standard CRUD operations (Create, Read, Update, Delete) via structured Java classes.
Important Classes and Methods
SQLiteOpenHelper: Abstract helper class used to manage database creation and schema versioning.
onCreate(SQLiteDatabase db): Called when the database is first created.
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion): Called when the database schema changes.
SQLiteDatabase: Provides methods to execute SQL queries.
insert(String table, String nullColumnHack, ContentValues values): Inserts a new record.
query(...) / rawQuery(String sql, String[] selectionArgs): Runs SQL queries and returns a Cursor.
ContentValues: Map-like object used to store key-value pairs corresponding to column names and column data.
Cursor: Pointer mechanism used to iterate through database query results.
XML Code
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<Button
android:id="@+id/btnDatabaseAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test SQLite DB" />
<TextView
android:id="@+id/tvStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textSize="18sp" />
</LinearLayout>
JAVA Code
DatabaseHelper.java
package com.example.sqlitedemo;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "AppDatabase.db";
private static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "users";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean insertData(String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
long result = db.insert(TABLE_NAME, null, contentValues);
return result != -1;
}
public String getFirstUser() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT name FROM " + TABLE_NAME, null);
if (cursor.moveToFirst()) {
String name = cursor.getString(0);
cursor.close();
return name;
}
cursor.close();
return "No records found";
}
}
MainActivity.java
package com.example.sqlitedemo;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = new DatabaseHelper(this);
Button btn = findViewById(R.id.btnDatabaseAction);
TextView tvStatus = findViewById(R.id.tvStatus);
btn.setOnClickListener(v -> {
dbHelper.insertData("John Doe");
String user = dbHelper.getFirstUser();
tvStatus.setText("Inserted & Retrieved: " + user);
});
}
}
Sample Output
Tapping the test button creates the local SQLite table, inserts "John Doe", queries the database, and displays Inserted & Retrieved: John Doe on screen.
Creating a Simple Flutter Application
using Android Studio
Introduction
Flutter is Google's multi-platform UI toolkit used to build natively compiled apps for mobile, web, and desktop from a single Dart codebase. Android Studio supports Flutter development via specialized Flutter and Dart plugins that provide project templates, hot reload features, and device debugging tools.
Main Attributes / Steps
Environment Setup: Install the Flutter SDK and enable the Flutter and Dart plugins inside Android Studio.
Create Project: Open Android Studio → Select New Flutter Project → Configure Flutter SDK Path → Set project name and language options (Dart).
Project Structure: Locate lib/main.dart which serves as the application entry point containing the main() function and widget tree.
Run Application: Connect an Android Virtual Device (AVD) or physical phone, then click the green Run icon to compile and deploy.
XML Code
Note: Flutter uses Dart to programmatically define UI widgets, so traditional Android XML layout files are not used.
Dart Code (lib/main.dart)
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Simple Flutter App',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo'),
),
body: const Center(
child: Text(
'Hello, Flutter World!',
style: TextStyle(fontSize: 22),
),
),
),
);
}
}
JAVA Code
Not applicable for core Flutter UI logic, as Flutter builds user interfaces using Dart code.
Sample Output
An application opens with a standard top App Bar displaying Flutter Demo and a centered text message reading Hello, Flutter World!.
Login System using SQLite with Username and Password Validation
Introduction
A basic login system validates user credentials against stored local database entries. This implementation builds an SQLite helper class to store registered credentials and query input strings to verify whether matching username and password combinations exist.
Main Attributes
EditText: Captures user inputs for username and password fields.
android:inputType="textPassword": Masks password text entry.
SQLiteDatabase.rawQuery(...): Runs a parameter-bound selection query (WHERE username=? AND password=?) to prevent SQL injection issues.
XML Code
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<EditText
android:id="@+id/etUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username" />
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:hint="Password"
android:inputType="textPassword" />
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="Login" />
</LinearLayout>
JAVA Code
UserDatabaseHelper.java
package com.example.loginsystem;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class UserDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "UserDB.db";
private static final int DB_VERSION = 1;
public UserDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT)");
// Seed default record
ContentValues cv = new ContentValues();
cv.put("username", "admin");
cv.put("password", "12345");
db.insert("users", null, cv);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS users");
onCreate(db);
}
public boolean validateUser(String username, String password) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM users WHERE username = ? AND password = ?",
new String[]{username, password});
boolean exists = cursor.getCount() > 0;
cursor.close();
return exists;
}
}
MainActivity.java
package com.example.loginsystem;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UserDatabaseHelper dbHelper = new UserDatabaseHelper(this);
EditText etUsername = findViewById(R.id.etUsername);
EditText etPassword = findViewById(R.id.etPassword);
Button btnLogin = findViewById(R.id.btnLogin);
btnLogin.setOnClickListener(v -> {
String user = etUsername.getText().toString().trim();
String pass = etPassword.getText().toString().trim();
if (user.isEmpty() || pass.isEmpty()) {
Toast.makeText(MainActivity.this, "Please fill all fields", Toast.LENGTH_SHORT).show();
} else {
boolean isValid = dbHelper.validateUser(user, pass);
if (isValid) {
Toast.makeText(MainActivity.this, "Login Successful!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Invalid Credentials", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Sample Output
Entering admin and 12345 displays a short Toast message reading Login Successful!. Typing incorrect credentials displays Invalid Credentials.
Store and Retrieve Customer Details using SQLite
Introduction
SQLite is an embedded relational database engine in Android used for storing structured offline data. This application demonstrates how to store and retrieve customer records containing CustID, Name, Age, and Place using an SQLiteOpenHelper subclass along with ContentValues and Cursor objects.
Main Attributes
SQLiteOpenHelper: Class responsible for managing database creation and version updates.
ContentValues: Key-value container used to pass data columns to database insert/update operations.
Cursor: Data pointer mechanism used to read rows returned by database queries.
CustID, Name, Age, Place: Customer data columns stored in the database.
XML Code
res/layout/activity_main.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<EditText
android:id="@+id/etCustId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Customer ID"
android:inputType="number" />
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name" />
<EditText
android:id="@+id/etAge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Age"
android:inputType="number" />
<EditText
android:id="@+id/etPlace"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Place" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<Button
android:id="@+id/btnSave"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Save" />
<Button
android:id="@+id/btnView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="View All" />
</LinearLayout>
<TextView
android:id="@+id/tvDisplay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textSize="16sp" />
</LinearLayout>
JAVA Code
CustomerDatabaseHelper.java
Java
package com.example.customerdb;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CustomerDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "CustomerDB.db";
private static final int DB_VERSION = 1;
public static final String TABLE_NAME = "customers";
public CustomerDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (CustID INTEGER PRIMARY KEY, Name TEXT, Age INTEGER, Place TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean insertCustomer(int custId, String name, int age, String place) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("CustID", custId);
cv.put("Name", name);
cv.put("Age", age);
cv.put("Place", place);
long result = db.insert(TABLE_NAME, null, cv);
return result != -1;
}
public String getAllCustomers() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
StringBuilder builder = new StringBuilder();
while (cursor.moveToNext()) {
int id = cursor.getInt(0);
String name = cursor.getString(1);
int age = cursor.getInt(2);
String place = cursor.getString(3);
builder.append("ID: ").append(id)
.append(" | Name: ").append(name)
.append(" | Age: ").append(age)
.append(" | Place: ").append(place)
.append("\n");
}
cursor.close();
return builder.length() > 0 ? builder.toString() : "No customer records found.";
}
}
MainActivity.java
Java
package com.example.customerdb;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomerDatabaseHelper dbHelper = new CustomerDatabaseHelper(this);
EditText etCustId = findViewById(R.id.etCustId);
EditText etName = findViewById(R.id.etName);
EditText etAge = findViewById(R.id.etAge);
EditText etPlace = findViewById(R.id.etPlace);
Button btnSave = findViewById(R.id.btnSave);
Button btnView = findViewById(R.id.btnView);
TextView tvDisplay = findViewById(R.id.tvDisplay);
btnSave.setOnClickListener(v -> {
String idStr = etCustId.getText().toString().trim();
String name = etName.getText().toString().trim();
String ageStr = etAge.getText().toString().trim();
String place = etPlace.getText().toString().trim();
if (idStr.isEmpty() || name.isEmpty() || ageStr.isEmpty() || place.isEmpty()) {
Toast.makeText(this, "Fill all fields", Toast.LENGTH_SHORT).show();
return;
}
boolean inserted = dbHelper.insertCustomer(
Integer.parseInt(idStr), name, Integer.parseInt(ageStr), place);
if (inserted) {
Toast.makeText(this, "Customer Saved!", Toast.LENGTH_SHORT).show();
etCustId.setText("");
etName.setText("");
etAge.setText("");
etPlace.setText("");
} else {
Toast.makeText(this, "Save Failed (Duplicate ID?)", Toast.LENGTH_SHORT).show();
}
});
btnView.setOnClickListener(v -> {
String data = dbHelper.getAllCustomers();
tvDisplay.setText(data);
});
}
}
Sample Output
Entering 101, Alice, 28, and New York then clicking Save stores the record. Clicking View All updates the text area to show:
ID: 101 | Name: Alice | Age: 28 | Place: New York
2. Steps to Create an SQLite Database and Perform Basic CRUD Operations
Introduction
CRUD stands for Create, Read, Update, and Delete—the four foundational data management operations. In Android, database setup and CRUD operations are managed by creating a custom class that inherits from SQLiteOpenHelper.
Main Attributes / Steps
Define SQLiteOpenHelper Helper Class: Extend SQLiteOpenHelper and override onCreate() to execute CREATE TABLE queries and onUpgrade() for schema changes.
Create (Insert): Call getWritableDatabase() and pass column data to db.insert() using ContentValues.
Read (Select): Call getReadableDatabase() and query table rows with db.query() or db.rawQuery() to get a Cursor.
Update: Call db.update() with modified ContentValues matching target selection criteria (WHERE clause).
Delete: Call db.delete() matching selection parameters to remove records.
XML Code
res/layout/activity_main.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="24dp">
<EditText
android:id="@+id/etId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ID"
android:inputType="number" />
<EditText
android:id="@+id/etItemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Item Name" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<Button
android:id="@+id/btnCreate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Insert" />
<Button
android:id="@+id/btnRead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Read" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnUpdate"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Update" />
<Button
android:id="@+id/btnDelete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Delete" />
</LinearLayout>
<TextView
android:id="@+id/tvOutput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textSize="16sp" />
</LinearLayout>
JAVA Code
CrudDatabaseHelper.java
Java
package com.example.crudsqlite;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CrudDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "CrudDB.db";
private static final int DB_VERSION = 1;
public static final String TABLE_NAME = "items";
public CrudDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY, name TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
// CREATE
public boolean insertData(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("id", id);
cv.put("name", name);
return db.insert(TABLE_NAME, null, cv) != -1;
}
// READ
public String readData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
StringBuilder sb = new StringBuilder();
while (cursor.moveToNext()) {
sb.append("ID: ").append(cursor.getInt(0))
.append(", Name: ").append(cursor.getString(1))
.append("\n");
}
cursor.close();
return sb.toString();
}
// UPDATE
public boolean updateData(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("name", name);
int rows = db.update(TABLE_NAME, cv, "id = ?", new String[]{String.valueOf(id)});
return rows > 0;
}
// DELETE
public boolean deleteData(int id) {
SQLiteDatabase db = this.getWritableDatabase();
int rows = db.delete(TABLE_NAME, "id = ?", new String[]{String.valueOf(id)});
return rows > 0;
}
}
MainActivity.java
package com.example.crudsqlite;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CrudDatabaseHelper db = new CrudDatabaseHelper(this);
EditText etId = findViewById(R.id.etId);
EditText etName = findViewById(R.id.etItemName);
TextView tvOutput = findViewById(R.id.tvOutput);
findViewById(R.id.btnCreate).setOnClickListener(v -> {
boolean ok = db.insertData(Integer.parseInt(etId.getText().toString()), etName.getText().toString());
Toast.makeText(this, ok ? "Inserted" : "Error", Toast.LENGTH_SHORT).show();
});
findViewById(R.id.btnRead).setOnClickListener(v -> tvOutput.setText(db.readData()));
findViewById(R.id.btnUpdate).setOnClickListener(v -> {
boolean ok = db.updateData(Integer.parseInt(etId.getText().toString()), etName.getText().toString());
Toast.makeText(this, ok ? "Updated" : "Update Failed", Toast.LENGTH_SHORT).show();
});
findViewById(R.id.btnDelete).setOnClickListener(v -> {
boolean ok = db.deleteData(Integer.parseInt(etId.getText().toString()));
Toast.makeText(this, ok ? "Deleted" : "Delete Failed", Toast.LENGTH_SHORT).show();
});
}
}
Sample Output
Insert: Input 1 & Laptop → Tapping Insert shows toast Inserted.
Read: Tapping Read displays ID: 1, Name: Laptop.
Update: Input 1 & Desktop → Tapping Update changes record to ID: 1, Name: Desktop.
Delete: Input 1 → Tapping Delete removes record from database.
Fragments in Android: Advantages, Lifecycle, and States
Introduction
A Fragment represents a modular segment of an Activity's user interface with its own lifecycle. Fragments must be embedded within a host activity, allowing flexible layout designs that adapt across smartphones and tablets.
Main Attributes & Advantages
Modularity & Reusability: Encapsulates UI sections and behavior into self-contained components reused across activities.
Multi-pane UI Support: Enables single-pane layouts on phones and side-by-side master-detail multi-pane layouts on tablets.
Dynamic Operations: Supports adding, removing, replacing, and backstack management using FragmentManager and FragmentTransaction.
Fragment States
Resumed (Running): Fragment is visible and active on screen with user focus.
Paused: Host activity is partially obscured or visible but lost focus.
Stopped: Fragment is no longer visible on screen (host activity stopped or fragment replaced).
Destroyed: Fragment instance is fully dismantled and removed from memory.
Fragment Lifecycle Callbacks
onAttach(): Fragment is tied to its host Activity context.
onCreate(): Fragment object instance is instantiated.
onCreateView(): Inflates and returns the Fragment's layout View.
onActivityCreated() / onViewCreated(): Indicates host activity and view tree setup is complete.
onStart(): Fragment becomes visible to the user.
onResume(): Fragment is active and capable of receiving user interactions.
onPause(): Fragment is leaving the active state.
onStop(): Fragment is hidden from screen.
onDestroyView(): Clean up resources related to the fragment layout View.
onDestroy(): Fragment state cleanup.
onDetach(): Fragment is disassociated from host Activity context.
XML Code
res/layout/fragment_lifecycle.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tvStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment Active"
android:textSize="22sp" />
</LinearLayout>
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
JAVA Code
LifecycleFragment.java
package com.example.fragmentlifecycle;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
public class LifecycleFragment extends Fragment {
private static final String TAG = "FragmentLifecycle";
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Log.d(TAG, "onAttach executed");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView executed");
return inflater.inflate(R.layout.fragment_lifecycle, container, false);
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume executed - State: Resumed");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "onPause executed - State: Paused");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "onDetach executed");
}
}
MainActivity.java
package com.example.fragmentlifecycle;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new LifecycleFragment())
.commit();
}
}
}
Sample Output
Launching the activity renders the fragment text Fragment Active on screen while logging lifecycle transition phases to Logcat:
D/FragmentLifecycle: onAttach executed
D/FragmentLifecycle: onCreateView executed
D/FragmentLifecycle: onResume executed - State: Resumed
No comments:
Post a Comment