Lập trình Android vớiJava – Học lập trình, học sử dụng máy tính từ số 0 – ZeZo.dev https://zezo.dev Sun, 01 Dec 2024 17:51:23 +0000 vi hourly 1 https://wordpress.org/?v=6.7.1 https://zezo.dev/wp-content/uploads/2024/11/cropped-zzel-32x32.png Lập trình Android vớiJava – Học lập trình, học sử dụng máy tính từ số 0 – ZeZo.dev https://zezo.dev 32 32 Hướng dẫn tạo notification trong android java https://zezo.dev/view/huong-dan-tao-notification-trong-android-java Sun, 01 Dec 2024 17:51:23 +0000 https://zezo.dev/?p=402 Tài liệu tham khảo https://developer.android.com/develop/ui/views/notifications/build-notification

Các bước dưới đây hướng dẫn bạn xây dựng các hàm dùng cho tạo Notify nhanh chóng

Bước 1: Khai báo biến ở phạm vi class

String CHANNEL_ID = "ID_chanel001";
String channel_name = "Kênh notify 001";
String channel_description = "Mô tả về chanel";

CHANEL_ID là id kênh truyền thông báo notify, dùng để phân biệt notify giữa các ứng dụng với nhau hoặc nội bộ ứng dụng.

Bước 2: Viết hàm khởi tạo CHANEL_ID

Chú ý: Notifycation Chanel chỉ có ở phên bản android từ API 26 trở lên. Dưới 26 thì không có..

void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = channel_name;
            String description = channel_description;
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

Bước 3: Viết hàm hiển thị notify showMyNotify()

void showMyNotify(int notificationId, String _title, String _content, boolean run_in_service) {

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(android.R.drawable.ic_lock_power_off)
                .setContentTitle(_title)
                .setContentText(_content)
                .setPriority(NotificationCompat.PRIORITY_DEFAULT);

        //--------------Trường hợp 1:  Dành cho chạy notify ở file service, broascast ... dạng background
//            startForeground(notificationId, builder.build()); // mở ghi chú dòng này và ẩn trường hợp 2 đi
        //----------------------------------

        //----------- Trường hợp 2: Dành cho chạy notify ở Activity, fragment
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.notify(notificationId, builder.build());
    }

Bước 4: Cách dùng

– Trường hợp 1 – Dùng notify ở activity: Bạn đưa code trên vào activity và chú ý trong hàm showMyNotify() dùng trường hợp 1

Trong hàm onCreate() của activity bạn gọi hàm tạo CHANEL_ID trước, sau đó bạn có thể dùng hàm showMyNotify() ở bất kỳ chỗ nào.

createNotificationChannel(); // dòng này phải để ở hàm onCreate()

//2 dòng dưới bạn có thể để ở bất kỳ đâu trong file activity
showMyNotify(1, "THông báo 1", "Nội dung 1");
showMyNotify(2, "THông báo 2", "Nội dung 2");

 

 Trường hợp 2 – Dùng notify ở service: Bạn đưa code trên vào file service và chú ý trong hàm showMyNotify() dùng trường hợp 2, ghi chú ẩn trường hợp 1 đi

Trong service thì bạn gọi hàm tạo CHANEL_ID ở trong hàm onCreate()

@Override
    public void onCreate() {
        super.onCreate();

        createNotificationChannel();// tạo chanel
    }

Sau đó bạn có thể dùng hàm showMyNotify ở trong hàm onStartCommand()

showMyNotify(1, "Thông báo trong service ", "Nội dung câu thông báo");

Xong rồi, bạn có thể chạy thử nghiệm nhé. Chúc bạn thành công.

 

]]>
Hướng dẫn tạo Bottom Navigation đơn giản trong android https://zezo.dev/view/huong-dan-tao-bottom-navigation-don-gian-trong-android Sun, 01 Dec 2024 17:48:27 +0000 https://zezo.dev/?p=400 1. Trong layout của Activity: Tạo thêm 1 thẻ BottomNavigationView

Thẻ đó là com.google.android.material.bottomnavigation.BottomNavigationView

Đặt id là: bottom_nav_bar

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottom_nav_bar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:menu="@menu/bottom_nav_item"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintHorizontal_bias="1"
    app:layout_constraintVertical_bias="1" />

2. Kích phải lên thư mục res/ tạo file menu có tên là bottom_nav_item

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:title="Phone" android:id="@+id/nav_phone" />
    <item android:title="Address" android:id="@+id/nav_address"/>
    <item android:title="Setting" android:id="@+id/nav_setting" />
</menu>

3. Trong MainActivity.java thêm các code sau vào hàm onCreate

BottomNavigationView bottomNavigationView;
        bottomNavigationView = findViewById(R.id.bottom_nav_bar);
        
        bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                // viết code xử lý click ở đây, dùng switch case kiểm tra item menu tương ứng
                switch (item.getItemId()){
                    case R.id.nav_phone:
                        // công việc với phone ở đây
                        break;
                    case R.id.nav_address:
                        //...
                        break;
                }

                return true; // return là true thì mới có hiệu ứng chọn phần tử
            }
        });

        bottomNavigationView.setOnItemReselectedListener(new NavigationBarView.OnItemReselectedListener() {
            @Override
            public void onNavigationItemReselected(@NonNull MenuItem item) {
                
            }
        });

Chạy và thử nghiệm tính năng

]]>
Bảng các action Intent https://zezo.dev/view/bang-cac-action-intent Fri, 29 Nov 2024 17:54:41 +0000 https://zezo.dev/?p=317  

Stt Activity Action Intent & Miêu tả
1 ACTION_ALL_APPS

Liệt kê tất cả ứng dụng có sẵn trên thiết bị

2 ACTION_ANSWER

Xử lý một cuộc gọi đến

3 ACTION_ATTACH_DATA

Được sử dụng để chỉ rằng một số phần dữ liệu nên được gắn kết tới một số vị trí khác

4 ACTION_BATTERY_CHANGED

Đây là một sticky broadcast chứa trạng thái nạp pin, mức độ, và thông tin khác về Battery

5 ACTION_BATTERY_LOW

Broadcast này tương ứng với thông báo từ hệ thống “Low battery warning”

6 ACTION_BATTERY_OKAY

Sẽ được gửi sau ACTION_BATTERY_LOW khi battery đã trở về trạng thái ok

7 ACTION_BOOT_COMPLETED

Đây là tín hiệu broadcast sau khi hệ thống đã kết thúc boot

8 ACTION_BUG_REPORT

Chỉ Activity để báo cáo một Bug

9 ACTION_CALL

Thực hiện một cuộc gọi tới ai đó đã được xác định bởi Data

10 ACTION_CALL_BUTTON

Người dùng nhấn nút “call” để tới dialer hoặc UI thích hợp để tạo một cuộc gọi

11 ACTION_CAMERA_BUTTON

“Camera Button” bị nhấn

12 ACTION_CHOOSER

Hiển thị một Activity Chooser, cho phép người dùng chọn thứ họ muốn trước khi tiến hành

13 ACTION_CONFIGURATION_CHANGED

Cấu hình (orientation, locale, etc) hiện tại của thiết bị đã thay đổi

14 ACTION_DATE_CHANGED

Date đã thay đổi

15 ACTION_DEFAULT

Tương tự ACTION_VIEW, “standard” action mà được thực hiện trên mỗi phần của Data

16 ACTION_DELETE

Xóa Data đã cho từ Container của nó

17 ACTION_DEVICE_STORAGE_LOW

Một sticky broadcast chỉ điều kiện low memory trên thiết bị

18 ACTION_DEVICE_STORAGE_OK

Chỉ điều kiện low memory trên thiết bị không tồn tại nữa

19 ACTION_DIAL

Quay một số đã được xác định bởi Data

20 ACTION_DOCK_EVENT

Một sticky broadcast cho các thay đổi trong trạng thái dock của thiết bị

21 ACTION_DREAMING_STARTED

Được gửi sau khi hệ thống bắt đầu Dreaming

22 ACTION_DREAMING_STOPPED

Được gửi sau khi hệ thống dừng Dreaming

23 ACTION_EDIT

Cung cấp truy cập tường minh mà có thể sửa đổi đến Data đã cho

24 ACTION_FACTORY_TEST

Main entry cho factory test

25 ACTION_GET_CONTENT

Cho phép người dùng chọn một loại Data cụ thể và trả về nó

26 ACTION_GTALK_SERVICE_CONNECTED

Một kết nối GTalk đã được thành lập

27 ACTION_GTALK_SERVICE_DISCONNECTED

Một kết nối GTalk đã bị ngắt

28 ACTION_HEADSET_PLUG

Tai nghe được cắm vào hoặc rút ra

29 ACTION_INPUT_METHOD_CHANGED

Một phương thức input đã bị thay đổi

30 ACTION_INSERT

Chèn một item trống vào trong Container đã cho

31 ACTION_INSERT_OR_EDIT

Chọn một item đang tồn tại, hoặc chèn một item mới, và sau đó sửa đổi nó

32 ACTION_INSTALL_PACKAGE

Chạy installer của ứng dụng

33 ACTION_LOCALE_CHANGED

Locale của thiết bị hiện tại đã thay đổi

34 ACTION_MAIN

Bắt đầu một main entry point, khong mong chờ để nhận Data

35 ACTION_MEDIA_BUTTON

“Media Button” bị nhấn

36 ACTION_MEDIA_CHECKING

Media ngoại vi có mặt, và đang được kiểm tra

37 ACTION_MEDIA_EJECT

Người dùng muốn gỡ bỏ kho lưu media ngoại vi

38 ACTION_MEDIA_REMOVED

Media ngoại vi đã bị xóa

39 ACTION_NEW_OUTGOING_CALL

Một cuộc gọi ra ngoài đang chuẩn bị được đặt

40 ACTION_PASTE

Tạo một item mới trong Container đã cho, khởi tạo nó từ các nội dung hiện tại của Clipboard

41 ACTION_POWER_CONNECTED

Nguồn ngoại vi đã được kết nối với thiết bị

42 ACTION_REBOOT

Có reboot. Chỉ sử dụng cho System code

43 ACTION_RUN

Chạy Data, bất kể ý nghĩa của nó

44 ACTION_SCREEN_OFF

Được gửi sau khi màn hình bị tắt

45 ACTION_SCREEN_ON

Được gửi sau khi màn hình được bật lên

46 ACTION_SEARCH

Thực hiện một tìm kiếm

47 ACTION_SEND

Phân phối một số Data tới ai đó

48 ACTION_SENDTO

Gửi một thông báo tới ai đó đã cho bởi Data

49 ACTION_SEND_MULTIPLE

Phân phối nhiều Data tới ai đó

50 ACTION_SET_WALLPAPER

Chỉ các thiết lập để chọn wallpaper

51 ACTION_SHUTDOWN

Thiết bị đang tắt

52 ACTION_SYNC

Thực hiện một tiến trình đồng bộ hóa dữ liệu

53 ACTION_TIMEZONE_CHANGED

Timezone đã thay đổi

54 ACTION_TIME_CHANGED

Time đã được thiết lập

55 ACTION_VIEW

Hiển thị dữ liệu tới người dùng

56 ACTION_VOICE_COMMAND

Bắt đầu Voice Command

57 ACTION_WALLPAPER_CHANGED

Wallpaper hiện tại đã thay đổi

58 ACTION_WEB_SEARCH

Thực hiện một Web search

 

]]>
Code Tạo delay sau 5s trong android – có thể áp dụng cho màn hình chào https://zezo.dev/view/code-tao-delay-sau-5s-trong-android-co-the-ap-dung-cho-man-hinh-chao Fri, 29 Nov 2024 17:52:19 +0000 https://zezo.dev/?p=311 chú ý cần import gói:

 

import android.os.Handler; 

code dưới đây có thể viết trong activity để test thử, sau 5s sẽ tự tắt ứng dụng

 

final Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
@Override public void run() {
 // Công việc sẽ thực hiện sau 5s = 5000ms 
Toast.makeText(MainActivity.this, "Hết 5s đợi rồi, stop", Toast.LENGTH_LONG).show();
 finish(); 
} }, 5000); 

Bạn có thể áp dụng để làm màn hình chào….

]]>
Sử dụng Webview đơn giản https://zezo.dev/view/su-dung-webview-don-gian Fri, 29 Nov 2024 17:51:46 +0000 https://zezo.dev/?p=309 Webview là một widget dùng để nhúng nội dung trang web vào ứng dụng, có thể load từ URL hoặc từ chuỗi có sẵn.

Các bước thao tác tạo Webview:

1. Trong layout nhúng vào 1 thẻ Webview và đặt ID cho thẻ này là mWebview

<Webview 
android:id="@+id/mWebview" 
android:layout_height="451dp"
android:layout_width="match_parent"/>

2. Trong activity viết code java như sau:

     WebView mWebView = findViewById(R.id.mWebview);

        // cho phép javascript hoạt động
        mWebView.getSettings().setJavaScriptEnabled(true);

        final Activity activity = this;

        mWebView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                Log.d("zzzzzzzzz", "onProgressChanged: " + newProgress); // xem log tiến trình load
                super.onProgressChanged(view, newProgress);
            }
        });

        mWebView.setWebViewClient( new WebViewClient(){
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
// hiển thị lỗi nếu có lỗi xảy ra
                Toast.makeText(activity, error.getDescription() , Toast.LENGTH_SHORT).show();
            }
        });
        // load web online
      mWebView.loadUrl("https://zezo.dev");

3. Cấp quyền và chạy thử ứng dụng

<uses-permission android:name="android.permission.INTERNET" />

4. Nếu muốn load nội dung từ file HTML có sẵn thì copy file html vào trong thư mục asset

Tạo thư mục ass bằng cách kích phải chuột lên thư mục app –> new –> folder –> asset folder   –> để mặc định bấm finish.

Tiếp theo copy file html vào thư mục assets vừa sinh ra

Tiếp theo trong code java ở trên sửa đoạn code loadUrl thành code dưới đây

 // load từ file asset
        mWebView.loadUrl("file:///android_asset/a.html");

ở code của bạn thì phải thay thế tên file a.html thành file html của bạn, còn chuỗi android_asset thì bạn để nguyên.

Bạn có thể tạo thư mục con trong thư mục asset để chứa ảnh và nhúng vào html.

Chú ý phải khai báo sử dụng quyền trong mainifest nhé

]]>
Hướng dẫn sử dụng Firebase gửi thông báo trong Android java https://zezo.dev/view/huong-dan-su-dung-firebase-gui-thong-bao-trong-android-java Fri, 29 Nov 2024 17:45:39 +0000 https://zezo.dev/?p=303 1. Tạo project mới

2. Vào manifest khai báo quyền

<uses-permission android:name="android.permission.INTERNET" />

3. Copy lấy 1 cái ảnh vào drawable để làm biểu tượng

Ảnh bạn tự chọn thôi, chú ý tên file ảnh không dấu, không cách, không viết hoa, không có dấu trừ, bắt đầu là chữ cái không phải số.

4. Trong layout của MainActivity tạo 1 cái textview để nhận diện

android:text="Zezo.dev Demo firebase"
android:textSize="30dp"
android:padding="20dp"
android:textStyle="bold"

5. Tạo layout cho câu thông báo

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="20dp">

    <!-- Parent Layout of ImageView -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <!--Image to be displayed beside the notification text-->
        <ImageView
            android:id="@+id/icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:padding="5dp"
            android:src="@drawable/demo_android" />
    </LinearLayout>

    <!-- Parent layout for holding the Title and the Body-->
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:padding="5dp">

        <!-- TextView for Title -->
        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"
            android:textColor="#000"
            android:textStyle="bold" />

        <!-- TextView for Body -->
        <TextView
            android:id="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Message"
            android:textSize="15sp" />

    </LinearLayout>

</LinearLayout>

 

6. Tạo lớp FirebaseMessageReceiver để nhận notify

package vn.edu.spx.demofirebasenotify;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;

import androidx.core.app.NotificationCompat;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FirebaseMessageReceiver extends FirebaseMessagingService {
    // Override onMessageReceived() method to extract the
    // title and
    // body from the message passed in FCM
    @Override
    public void
    onMessageReceived(RemoteMessage remoteMessage) {
        // First case when notifications are received via
        // data event
        // Here, 'title' and 'message' are the assumed names
        // of JSON
        // attributes. Since here we do not have any data
        // payload, This section is commented out. It is
        // here only for reference purposes.
        /*if(remoteMessage.getData().size()>0){
            showNotification(remoteMessage.getData().get("title"),
                          remoteMessage.getData().get("message"));
        }*/

        // Second case when notification payload is
        // received.
        if (remoteMessage.getNotification() != null) {
            // Since the notification is received directly from
            // FCM, the title and the body can be fetched
            // directly as below.
            showNotification(
                    remoteMessage.getNotification().getTitle(),
                    remoteMessage.getNotification().getBody());
        }
    }

    // Method to get the custom Design for the display of
    // notification.
    private RemoteViews getCustomDesign(String title,
                                        String message) {
        RemoteViews remoteViews = new RemoteViews(
                getApplicationContext().getPackageName(),
                R.layout.layout_notify);
        remoteViews.setTextViewText(R.id.title, title);
        remoteViews.setTextViewText(R.id.message, message);
        remoteViews.setImageViewResource(R.id.icon,
                R.drawable.demo_android);
        return remoteViews;
    }

    // Method to display the notifications
    public void showNotification(String title,
                                 String message) {
        // Pass the intent to switch to the MainActivity
        Intent intent
                = new Intent(this, MainActivity.class);
        // Assign channel ID
        String channel_id = "notification_channel";
        // Here FLAG_ACTIVITY_CLEAR_TOP flag is set to clear
        // the activities present in the activity stack,
        // on the top of the Activity that is to be launched
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // Pass the intent to PendingIntent to start the
        // next Activity
        PendingIntent pendingIntent
                = PendingIntent.getActivity(
                this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);

        // Create a Builder object using NotificationCompat
        // class. This will allow control over all the flags
        NotificationCompat.Builder builder
                = new NotificationCompat
                .Builder(getApplicationContext(),
                channel_id)
                .setSmallIcon(R.drawable.demo_android)
                .setAutoCancel(true)
                .setVibrate(new long[]{1000, 1000, 1000,
                        1000, 1000})
                .setOnlyAlertOnce(true)
                .setContentIntent(pendingIntent);

        // A customized design for the notification can be
        // set only for Android versions 4.1 and above. Thus
        // condition for the same is checked here.
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.JELLY_BEAN) {
            builder = builder.setContent(
                    getCustomDesign(title, message));
        } // If Android Version is lower than Jelly Beans,
        // customized layout cannot be used and thus the
        // layout is set as follows
        else {
            builder = builder.setContentTitle(title)
                    .setContentText(message)
                    .setSmallIcon(R.drawable.demo_android);
        }
        // Create an object of NotificationManager class to
        // notify the
        // user of events that happen in the background.
        NotificationManager notificationManager
                = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        // Check if the Android Version is greater than Oreo
        if (Build.VERSION.SDK_INT
                >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel
                    = new NotificationChannel(
                    channel_id, "web_app",
                    NotificationManager.IMPORTANCE_HIGH);
            notificationManager.createNotificationChannel(
                    notificationChannel);
        }

        notificationManager.notify(0, builder.build());
    }
}

7.  Khai báo service trong mainifest

<service android:name=".FirebaseMessageReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

https://console.firebase.google.com/

]]>
Thực hành sử dụng RecyclerView trong android java p4 https://zezo.dev/view/thuc-hanh-su-dung-recyclerview-trong-android-java-p4 Fri, 29 Nov 2024 17:44:47 +0000 https://zezo.dev/?p=301 Cải tiến thêm sự kiện bấm vào 1 phần tử trong danh sách

Như ListView thông thường thì sử dụng setOnItemClick…. nhưng RecyclerView không dùng như vậy. Trên internet có nhiều hướng dẫn cách viết rất dài dòng, bạn hãy sử dụng CardView để thiết lập.

1. Sử dụng CardView theo hướng dẫn ở trên, cardview có đặt id là android:id=”@+id/car_view”

2. Vào file SanPhamViewHolder.java khai báo thêm thuộc tính cardview và findViewById giống như các textview trong đó

Phần khai báo: public CardView car_view;
Phần code trong hàm: car_view = itemView.findViewById(R.id.car_view);

3. Trong hàm onBindViewHolder của adapter, bạn thêm code sau ở cuối:

        final  int pos = position;
        holder.car_view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "Position " + pos, Toast.LENGTH_SHORT).show();
            }
        });

 

chạy thử để xem kết quả Toast, có được vị trí của phần tử hiện tại rồi thì làm gì là tùy bạn.

]]>
Thực hành sử dụng RecyclerView trong android java p3 https://zezo.dev/view/thuc-hanh-su-dung-recyclerview-trong-android-java-p3 Fri, 29 Nov 2024 17:44:23 +0000 https://zezo.dev/?p=299 Update: Dùng cardview để trình bày các item

Bạn thay thế layout của custom_item_layout.xml bằng layout dưới đây. Cơ bản là có 1 LinearLayout bọc ngoài rồi cho cái cardView vào trong để bao gói, bên trong đó tiếp tục cho 1 cái layout để trình bày các phần tử con.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="wrap_content">
   <com.google.android.material.card.MaterialCardView
       android:id="@+id/card_view"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       app:cardBackgroundColor="@color/teal_200"
       android:layout_margin="8dp"
       app:cardCornerRadius="10dp"
       android:clickable="true"
       android:focusable="true"
       android:longClickable="true"
       app:cardElevation="5dp"
       >
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:padding="10dp"
           >
           <TextView
               android:id="@+id/tv_id"
               android:textColor="#BC3636"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
           <TextView
               android:id="@+id/tv_name"
               android:textColor="#2196F3"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"/>
       </LinearLayout>
   </com.google.android.material.card.MaterialCardView>
</LinearLayout>

Một số thuộc tính của CardView:

app:cardBackgroundColor=”@color/teal_200″ ==> Màu nền cho cardview
android:layout_margin=”8dp” ===> tạo khoảng cách giữa các phần tử
app:cardCornerRadius=”10dp” ==> tạo bo tròn góc, cái này thì nên có padding kèm theo ở layout chứa trong cardview.
android:clickable=”true” ==> Cho phép bấm chọn hay không, mặc định là false, nó sẽ giống textview
android:focusable=”true” ==>Cho phép nhận focus thì nó sẽ giống vai trò của nút bấm
android:longClickable=”true” ==> Cho phép bấm giữ lâu
app:cardElevation=”5dp” ==> Khoảng cách chiều sâu (trục z trong hệ tọa độ), sẽ nhìn thấy đổ bóng

]]>
Thực hành sử dụng RecyclerView trong android java p2 https://zezo.dev/view/thuc-hanh-su-dung-recyclerview-trong-android-java-p2 Fri, 29 Nov 2024 17:43:57 +0000 https://zezo.dev/?p=297 Phần này: Cải tiến thêm nút bấm mỗi khi bấm nút sẽ thêm 1 dòng trong danh sách và tự động hiển thị lên danh sách

Bước 1: Trong layout của main activity thêm nút FloatButton:

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:id="@+id/fab_01"
        android:src="@android:drawable/ic_input_add"
        android:backgroundTint="#FF9800"
        />

– Thuộc tính: android:src=”@android:drawable/ic_input_add” dùng để tạo biểu tượng dấu + trong nút bấm
– Thuộc tính: android:backgroundTint=”#FF9800″ dùng để tạo màu nền cho nút bấm

Bước 2: Viết code cho sự kiện bấm nút, trong hàm onCreate của MainActivity.java viết vào cuối cùng của hàm code sau:

FloatingActionButton fab = findViewById(R.id.fab_01);

        fab.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                SanPham sp_them = new SanPham(88,"Sản phẩm thêm nè");  // tạo đối tượng sp mới

                list.add(sp_them); // đưa vào cái arraylist

                sanPhamAdapter.notifyDataSetChanged();  // thông báo cho adapter biết có thay đổi dữ liệu để cập nhật lên view

            }

        });

Nhớ là import gói:
import com.google.android.material.floatingactionbutton.FloatingActionButton;

Chạy lại ứng dụng để xem kết quả nhé!

]]>
DatePicker trong android java https://zezo.dev/view/datepicker-trong-android-java Fri, 29 Nov 2024 17:42:48 +0000 https://zezo.dev/?p=295 Hướng dẫn dùng DatePicker gắn trực tiếp trên layout của activity

Bước 1: Trên layout thả vào 1 view là DatePicker

    <DatePicker
        android:id="@+id/dpk_01"
        android:layout_width="316dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

Bước 2: Viết code java trong activity

  DatePicker datePicker = findViewById(R.id.dpk_01);

        // sử dụng đối tượng lịch để cài đặt
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis( System.currentTimeMillis() );
        // điều khiển datepicker
        // init(int year, int monthOfYear, int dayOfMonth, DatePicker.OnDateChangedListener onDateChangedListener)
        datePicker.init(
                calendar.get(Calendar.YEAR) ,
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DATE),
                new DatePicker.OnDateChangedListener() {
                    @Override
                    public void onDateChanged(DatePicker datePicker, int i, int i1, int i2) {
                        int nam = i;
                        int thang = i1; // nhận giá trị từ 0 -> 11
                        int ngay = i2;

                        String chuoi_ngay_thang = ngay + "/" + (thang + 1) + "/" + nam;
                        // Đến đây bạn đã lấy được ngày tháng khi người dùng chọn
                        Log.d("zzzzzzzzzz","Ngay thang chon: " + chuoi_ngay_thang);
                        
                    }
                }
        );

Bước 3: Chạy thử ứng dụng, chọn ngày tháng và xem logcat

]]>