Tải bản đầy đủ (.docx) (50 trang)

Tổng hợp kĩ thuật android nâng cao và sử dụng firebase

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (713.44 KB, 50 trang )

T ổng h ợp các k ĩ thu ật Android nâng cao
tác gi ả:V ũXuân Tr ườ
ng
Google Store: />Bài 1: Gi ới thi ệu chung v ề Android
1. Android là gì?
-Là một hệ điều hành trên các thiết bị di động smartphone
được phát triển bới Google dựa trên hệ điều hành Linux.
-Các ứng dụng Android đều phát triển dựa trên ngôn ngữ
Java
2. Tại sao phải học Android?
-Ngày nay thiết bị di động sử dụng Android phát triển ngày
càng mạnh mẽ
3. Những kiến thức căn bản để học Android
-Căn bản về kĩ thuật lập trình
-Java căn bản
-Chịu khó
Bài 2: Cách cài máy ảo chính thống Emulator của Android
Studio
Bước 1: Tải và cài Android Studio trên trang
chủ của
Android( />o)
Bước 2: Tải phần mềm hỗ trợ tăng tốc đồ họa
cho cấu hình máy tính Identification Utility:
-Lên Google search từ khóa:"intel® processor
identification utility":


-chọn phiên bản phù hợp với cấu hình máy tính và tải về
cài đặt:

-sau khi cài đặt phần mềm chạy Android Studio và tiến


hành cài máy ảo Emulator bình thường


Bài 4:Hiển thị danh sách đối tượng trên ListView dùng
Custom ArrayAdapter
Bước 1: item xml:
<?xml version="1.0" encoding="utf-8" ?>
- "match_parent" android:layout_height="match_parent" a
ndroid:orientation="vertical">
ayout_width="150dp" android:layout_height="170dp" app:
srcCompat="@drawable/bimatinhyeu" />
dth="match_parent" android:layout_height="wrap_conte
nt" android:text="TextView" android:textSize="26dp" />
dth="match_parent" android:layout_height="wrap_conte
nt" android:text="TextView" />
</LinearLayout>
Bước 2: Class Sach{}
public class Sach implements Serializable {
private int id;
private String tenSach;
private String giaSach;
private String emailDangNhap;
private int hinhAnh;
}

Bước 3: ArrayAdapter:
public class SachAdapter extends ArrayAdapter<Sach> {
Activity context;
int resource;


public SachAdapter(@NonNull Activity context, int
resource) {
super(context, resource);
this.context=context;
this.resource=resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View
convertView, @NonNull ViewGroup parent) {
View
customView=this.context.getLayoutInflater().inflate(this.res
ource,null);
TextView
txtTenSach=(TextView)customView.findViewById(R.id.txtT
enSach);
TextView
txtGiaSach=(TextView)customView.findViewById(R.id.txtGi
aSach);
ImageView
imgHinhAnhSach=(ImageView)customView.findViewById(
R.id.imgHinhAnhSach);
Sach sach=getItem(position);
txtTenSach.setText(sach.getTenSach());

txtGiaSach.setText(sach.getGiaSach()+"đồng");
imgHinhAnhSach.setImageResource(sach.getHinhAnh());
return customView;
}


}
Bài 5: Giới thiệu menu NavigationBottom thường dùng
trong các App
-Là loại Template thông dụng thường dùng trong rất nhiều các ứng dụng khác nhau
-Trong Android Studio:
File=>New=>New Project=> Bottom Navigation Activity:

- Phiên bản mới các menu là các Fragment:


Đây là UI của menu Navigation Bottom

Bài 6: Truy ền d ữ li ệu gi ữa các Fragment trong menu
Navigation Bottom


Dùng EventBust:
Vào trang chủ của
EventBust( để copy thư
viện và đọc cách sử dụng, ở đây tôi dùng phiên bản 2.4:
thư viện:
implementation 'de.greenrobot:eventbus:2.4.0'
Đối tượng truyền:
SinhVien{

ptivate int id;
private String name;
private String phone;
}
+Truyền dữ liệu:
SinhVien sinhVien=new SinhVien(01,Quyen,098);
EventBus.getDefault().postSticky(sinhVien);
+Nhận dữ liệu:
Override hai hàm onStart() và onStop();
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().registerSticky(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
// hàm này dùng để nhận đối tượng truyền có kiểu
SinhVien


public void onEventMainThread(SinhVien event) {
SinhVien sinhVienNhan=event;
Bài 7: Điều hướng giữa các Fragment trong menu
Navigation Bottom
Điều hướng giữa các Fragment trong menu Navigation Bottom:

- Tôi khai báo một Button ở menu Fragment Home;

Button btnChuyenSangNotify;
btnChuyenSangNotify=findviewbyid(R.id.btnChuyenSang
Notify);
-Muốn khi nhấn vào button chuyển sang menu Fragment
NoTifyCation tôi làm như sau:
btnChuyenSangNotify.setOnClickListener(){
Navigation.findNavController(btnChuyenSangNotify).navig
ate(R.id.navigation_notify);
}
trong đó, R.id.navigation_notify và id của menu navigation
notify:
Điều này giúp chúng ta thuận tiện hơn
VD: khi nhấn button đăng nhập sẽ chuyển sang menu mặt
hàng


Bài 9: Cách mở một Activity từ một Fragment và đồ ng thời
truyền dữ liệu
Cách 1:Dùng hàm getActivity để lấy Activity
hiện tại sau đó dùng hàm setContenView để
mở layout Activity
Class Sach{
private int id;
private String name;
private String gia;
}

Truyền đối tượng sach qua tham số vào hàm:
moChiTiet(Sach sach){
getActivity.setContentView(R.layout.item);


//Dùng getActivity để lấy Activity hiện tại và
findViewbyId
TextView txtId=getActivity().findViewbyId(R.id.txtId);
TextView txName=getActivity().findViewbyId(R.id.txtName);
TextView txtGia=getActivity().findViewbyId(R.id.txtGia);
txtId.setText(sach.getId());
txtName.setText(sach.getName());
txtGia.setText(sach.getGia());
}


Cách 2:
Bước 1: mở Activity từ Fragment:
Intent intent=new Intent(Fragment,Activity);
startActivity(intent);

Bước 2: Truyền dữ liệu:
Dùng EventBust ở bài 6

Bài 9: Cách m ở m ột Activity t ừ m ột Fragment và đồ ng th ời
truy ền d ữ li ệu
Cách 1:Dùng hàm getActivity để lấy Activity
hiện tại sau đó dùng hàm setContenView để
mở layout Activity
Class Sach{
private int id;
private String name;
private String gia;
}


Truyền đối tượng sach qua tham số vào hàm:
moChiTiet(Sach sach){
getActivity.setContentView(R.layout.item);

//Dùng getActivity để lấy Activity hiện tại và
findViewbyId
TextView txtId=getActivity().findViewbyId(R.id.txtId);
TextView txName=getActivity().findViewbyId(R.id.txtName);
TextView txtGia=getActivity().findViewbyId(R.id.txtGia);
txtId.setText(sach.getId());
txtName.setText(sach.getName());
txtGia.setText(sach.getGia());
}

Cách 2:
Bước 1: mở Activity từ Fragment:
Intent intent=new Intent(Fragment,Activity);
startActivity(intent);

Bước 2: Truyền dữ liệu:
Dùng EventBust ở bài 6

Bài 11: Mutiple Item RecyclerView, s ử d ụng cùng m ột lúc
nhi ều custom item trên RecyclerView
Ta có 2 xml item1, item2
Ta có Class sau:


public class Text1 {

private int viewType;
private String text;
private int hinhAnh;
}
Ta khai báo Adapter như sau:
public class ManHinhChatAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<Text1> mTests=new ArrayList<Text1>();
private LayoutInflater mLayoutInflater;
private Context context;
public ManHinhChatAdapter(List<Text1>
mTests,Context context) {
this.mTests=mTests;
this.context=context;
}
// khai báo lớp hiển thị item1
class ViewHolder0 extends RecyclerView.ViewHolder {
ImageView imgHinhAnh;
public ViewHolder0(View itemView){
super(itemView);
imgHinhAnh=itemView.findViewById(R.id.imgHinhAnh);
}
}
// khai báo lớp hiển thị item2
class ViewHolder2 extends RecyclerView.ViewHolder {
ImageView imgHinhAnh2;
TextView txtText2;
public ViewHolder2(View itemView){



super(itemView);
imgHinhAnh2=itemView.findViewById(R.id.imgHinhAnh2);
txtText2=itemView.findViewById(R.id.txtTextView2);
}
}
@Override
public int getItemViewType(int position) {
switch(mTests.get(position).getViewType()){
// nếu getViewType() là 0 trả về 0
case 0:
return mTests.get(position).getViewType();
// nếu getViewType() là 1 trả về 1
case 1:
return mTests.get(position).getViewType();
default:
return -1;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder
onCreateViewHolder(@NonNull ViewGroup parent, int
viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
switch (viewType){
// nếu viewType là 0 trả về class hiển thị item1
case 0:



View item0 =
inflater.inflate(R.layout.item1,parent,false);
return new ViewHolder0(item0);
// nếu viewType là 1 trả về class hiển thị item2
case 1:
View item2 =
inflater.inflate(R.layout.item2,parent,false);
return new ViewHolder2(item2);
default:
return null;
}
}
@Override
public void onBindViewHolder(@NonNull
RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()){
// nếu viewType là 0 lấy đối tượng và xử lý
case 0:
ViewHolder0 viewHolder0 =
(ViewHolder0)holder;
int
hinhANh1=mTests.get(position).getHinhAnh();
((ViewHolder0)
holder).imgHinhAnh.setImageResource(hinhANh1);
break;
// nếu viewType là 1 lấy đối tượng và xử lý
case 1:
ViewHolder2 viewHolder2 =
(ViewHolder2)holder;
String text1=mTests.get(position).getText();



int hinhAnh2=mTests.get(position).getHinhAnh();
((ViewHolder2) holder).txtText2.setText(text1);
((ViewHolder2)
holder).imgHinhAnh2.setImageResource(hinhAnh2);
break;
}
}
@Override
// tổng số phần tử của mảng cần hiển thị
public int getItemCount() {
return mTests.size();
}
}
Ở MainActivity:
RecyclerView recyclerView;
ManHinhChatAdapter manHinhChatAdapter;
ArrayList<Text1>danhSachs=new ArrayList<Text1>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=findViewById(R.id.rcDanhSach);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(this);
manHinhChatAdapter=new
ManHinhChatAdapter(danhSachs,MainActivity.this);
recyclerView.setAdapter(manHinhChatAdapter);
recyclerView.setLayoutManager(linearLayoutManager);

// khởi tạo các phần tử của mản hiển thị lên RecyclerView


danhSachs.add(new Text1(0,"Book
1",R.drawable.cungcontruongthanh));
danhSachs.add(new Text1(1,"Book
2",R.drawable.mackethienha));
danhSachs.add(new Text1(0,"Book
3",R.drawable.bimatinhyeu));
danhSachs.add(new Text1(1,"Book
4",R.drawable.dambinghet));
danhSachs.add(new Text1(0,"Book
5",R.drawable.damuocmo));
danhSachs.add(new Text1(1,"Book
6",R.drawable.kynangditruocdamme));
danhSachs.add(new Text1(0,"Book
7",R.drawable.nghethuatdamphan));
danhSachs.add(new Text1(1,"Book
8",R.drawable.danhthucnanglucvohan));
danhSachs.add(new Text1(0,"Book
9",R.drawable.doingandungngudai));
danhSachs.add(new Text1(1,"Book
10",R.drawable.mackethienha));
danhSachs.add(new Text1(0,"Book
11",R.drawable.mackethienha));
Một cách khác truyền dữ liệu giữa các Activity và Frafment:
đó là dùng biến static
public static Sinhvien sv;
lấy biến
Fragment.sv hoặc Activity.sv

Bài 13: Cách thêm dữ liệu vào RealTime Database Firebase
Khai báo 2 biến:
FirebaseDatabase firebaseDatabase;


// khai báo biến đường dẫn databaseReference
DatabaseReference databaseReference;
firebaseDatabase=FirebaseDatabase.getInstance();
// thêm nút ChoBayBan vào đường dẫn
databaseReference=firebaseDatabase.getReference().child("Cho
BayBan");
// khởi tạo một mảng ArrayList
ArrayList<MatHang>dsMatHangs=new
ArrayList<MatHang>();
// thêm một mặt hàng vào dsMatHangs
dsMatHangs.add(matHang);
// thêm mảng ArrayList vào đường dẫn
databaseReference.add(dsMatHangs);

Bài 14: Cách đọc mảng đối tượng từ RealTime Database để
thêm vào ListView, GridView, RecyclerView
Fragment, Activity kế thừa phương thức implements ValueEventListener
khai báo 2 biến:
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
firebaseDatabase=FirebaseDatabase.getInstance();


databaseReference=firebaseDatabase.getReference().child("ChoBayBan");
// thêm sự kiện addValueEventListener

databaseReference.addValueEventListener(this);
Override 2 hàm sau:
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
// khởi tạo một mảng ArrayList ds1 để chứa các phần tử từ đường dẫn
ArrayList<HangBayBan> ds1=new ArrayList<HangBayBan>();
Iterable<DataSnapshot>dataSnapshots=dataSnapshot.getChildren();
for(DataSnapshot dataSnapshot1:dataSnapshots){
// ép kiểu về HangBayBan
HangBayBan hangBayBan=dataSnapshot1.getValue(HangBayBan.class);
ds1.add(hangBayBan)
}
// hàm clear() để xóa toàn bộ phần tử của mảng và adapter
hangBayBans.clear();
hangBayBanAdapter.clear();
// thêm các phần tử từ đường dẫn vào adapter để hiển thị
hangBayBans.addAll(ds1);
hangBayBanAdapter.addAll(hangBayBans);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}

Bài 15: Cách s ử d ụng l ưu tr ữ file Storage, ImageView,
VideoView
Muốn sử dụng Storage thì thư viện Storage và thư viện
Autithencation phải cùng một phiên bản, ở đây mình lấy
phiên bản 16.1.0:
Khai báo hai biến sau:
FirebaseStorage firebaseStorage;

StorageReference storageReference;
firebaseStorage=FirebaseStorage.getInstance();
storageReference=firebaseStorage.getReference();
Dùng hình ảnh:+Download:
// trỏ đến thư mục photos và download hình ảnh
hangBayBan.getHinhAnh1().jpg hiển thị lên ImageView
imgHinhAnhChiTiet1:


StorageReference
storageReference1=storageReference.child("photos/"+han
gBayBan.getHinhAnh1()+".jpg");
long mega=1024*1024;
storageReference1.getBytes(mega).addOnSuccessListen
er(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
Bitmap bitmap=
BitmapFactory.decodeByteArray(bytes,0,bytes.length);
imgHinhAnhChiTiet1.setImageBitmap(bitmap);
}
})
+Tải hình ảnh lên:
// tải hình ảnh bitmap1 lấy từ đa phương tiện tải lên với
tên hangBayBans.size()+intbitmap1 + ".jpg"
int intbitmap1 = random.nextInt();
ByteArrayOutputStream
byteArrayOutputStream = new ByteArrayOutputStream();
bitmap1.compress(Bitmap.CompressFormat.JPEG, 100,
byteArrayOutputStream);

byte[] data =
byteArrayOutputStream.toByteArray();
storageReference.child(hangBayBans.size()+intbitmap1 +
".jpg").putBytes(data);
Dùng VideoView:+Download video hiển thị
lên videoView:


// trỏ đến thư mục videos và download video có tên
baiHoc.avi, sau đó hiển thị lên VideoView
btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
storageReference.child("videos/"+baiHoc+".avi").getDownl
oadUrl().addOnSuccessListener(new
OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
Toast.makeText( ItemChiTiet.this,"Đang
chạy videos/"+baiHoc+".avi, xin chờ trong giây
lát!",Toast.LENGTH_SHORT).show();
videoView.setVideoURI(uri);
videoView.setMediaController(new
MediaController(ItemChiTiet.this));
videoView.start();
}
});
}
});
Bài 16: Cách sử dụng Notifycation trong Firebase

Muốn sử dụng Notifycation thì tất cả các thư
viện Autithencation, database, core, message
đều phải cùng một phiên bản, ở đây mình lấy
phiên bản 10.2.1:
implementation 'com.google.firebase:firebase-auth:10.2.1'
implementation 'com.google.firebase:firebasedatabase:10.2.1'


implementation 'com.google.firebase:firebase-core:10.2.1'
implementation 'com.google.firebase:firebasemessaging:10.2.1'
Lớp MessagingService dùng để put một
notifycation
public class MessagingService extends
FirebaseMessagingService {
private static final String TAG = "MyFirebaseService";
public void onMessageReceived(RemoteMessage
remoteMessage) {
super.onMessageReceived(remoteMessage);
sendNotification(remoteMessage.getNotification().getBody
());
}
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
// TODO: Implement this method to send token to
your app server.
}
private void sendNotification(String messageBody) {

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent =


PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = getString(R.string.project_id);
Uri defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_
NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_launcher_background)
.setLargeIcon(BitmapFactory.decodeResource(getResour
ces(), R.drawable.ic_launcher_background))
// tiêu đề của mã text
.setContentTitle("Shoppe Demo, Khuyến
Mãi Khủng!")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.addAction(new NotificationCompat.Action(
android.R.drawable.sym_call_missed,
"Cancel",
PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT)))

.addAction(new NotificationCompat.Action(


android.R.drawable.sym_call_outgoing,
"OK",
PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT)));
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.O) {
NotificationChannel channel = new
NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0,
notificationBuilder.build());
}
}
Bài 21: SearchView và Option menu trong Fragment
Thêm hàm setHasOptionsMenu(true) ở sau
onCreatView như sau:


public View onCreateView(@NonNull LayoutInflater inflater,

ViewGroup container, Bundle savedInstanceState) {

setHasOptionsMenu(true);

homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);

Override hai hàm sau:
// hàm dùng để khai báo Search và Option menu
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.mnu_search, menu);
MenuItem item = menu.findItem(R.id.mnu_search);

// chỉnh sửa chế độ hiển thị của ô tìm kiếm IFROOM,
ALWAYS,...
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW |
MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
ArrayList<HangBayBan>ds1=new ArrayList<HangBayBan>();
for(HangBayBan matHang:hangBayBans){
if(matHang.getTen().contains(query)){
ds1.add(matHang);
}
}
hangBayBanAdapter.clear();

hangBayBanAdapter.addAll(ds1);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// Here is where we are going to implement the filter logic
return true;
}
});
}

// hàm dùng để chọn case của option menu
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.mnu_thoat:
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startActivity(startMain);
break;
}


return super.onOptionsItemSelected(item);
}
}

Bài 19: S ử d ụng ScrollView để hi ển th ị đo ạn text dài
Bài 20: L ấy hình ảnh t ừ Đa Ph ươ ng Ti ện hi ển th ị lên
ImageView

Tạo sự kiện khi ta click vào ImageView:
PICK_IMAGE_REQUEST là biến requestCode là mã số
để xác định hình ảnh được lưu
imgHinhAnh1.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select
Picture"), PICK_IMAGE_REQUEST);
}
});
Override hàm sau:
@Override
public void onActivityResult(int requestCode, int
resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode,
data);
if(resultCode == RESULT_OK
&& data != null && data.getData() != null )
{
filePath = data.getData();


try {
Bitmap bitmap =
MediaStore.Images.Media.getBitmap(getActivity().getCont
entResolver(), filePath);

if(requestCode == PICK_IMAGE_REQUEST) {
// hiển thị hình ảnh lên ImageView:
imgHinhAnh1.setImageBitmap(bitmap);
bitmap1=bitmap;
}
if(requestCode == PICK_IMAGE_REQUEST2) {
imgHinhAnh2.setImageBitmap(bitmap);
bitmap2=bitmap;
}
if(requestCode == PICK_IMAGE_REQUEST3) {
imgHinhAnh3.setImageBitmap(bitmap);
bitmap3=bitmap;
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Bài 22: Drawable custom các widget và theme
notifyItemInsert(int) trong RecyclerView
Dùng để đưa các phần tử lên RecyvlerView tức thì:
Adapter.notifyItemInsert( position);


×