บทความนี้จะมีเนื้อหาเกี่ยวกับ Firebase Realtime Database, Firebase Storage, Firebase Crash, Drawer Menu, Fragment, Custom ListView, Camera,Glide และอื่นๆสัพเพเหระ ออกตัวไว้ก่อนคือผมอธิบายไม่ค่อยเก่งนะครับ ดังนั้นเน้นดู Code แล้วจิ้นกันเอาเองเนาะ 5555
เริ่มกันเลยดีกว่า เราจะมาสร้างแอปที่มีรายละเอียดดังต่อไปนี้
- หน้า ListView เอาไว้แสดง Content ซึ่งมี Header, Content, TimeStamp, Image
- สามารถ Create, Read, Update, Delete ได้
สร้างโปรเจคให้มี Navigation Drawer หรือดูจากบทความนี้ How to Add a Navigation Drawer and Implement Fragment
สร้างไฟล์ MainFragment.java โดยมีโครงสร้างดังนี้
public class MainFragment extends Fragment { public MainFragment() { super(); } public static MainFragment newInstance(){ MainFragment fragment = new MainFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } @Override public void onStart() { super.onStart(); } @Override public void onStop() { super.onStop(); } /* * Save Instance State Here */ @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save Instance State here } /* * Restore Instance State Here */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (savedInstanceState != null) { // Restore Instance State here } } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } }
สร้าง layout ไฟล์ flagment_main.xml ให้มี ListView และ Floating Action Button
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_margin="@dimen/fab_margin" app:srcCompat="@android:drawable/ic_input_add" /> </RelativeLayout>
—
ใน MainActivity.java ทำการเพิ่มเมธอด initFragment เพื่อให้ MainFragment เปิดอัตโนมัติเป็น Fragment แรก
private void initFragment(Bundle savedInstanceState) { if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.contentContainer, MainFragment.newInstance()) .commit(); } }
—
–
ที่ไฟล์ activity_main_drawer.xml แก้ไขให้เหลือเมนูเดียวคือ Firebase News
ที่ MainActivity.java เพิ่มเมธอด openMainFragment เพื่อให้เมื่อกดเมนู Fragment News ที่ Drawer Menu แล้วแสดง MainFragment
—
private void openMainFragment() { Fragment fragment = getSupportFragmentManager() .findFragmentById(R.id.contentContainer); if (fragment instanceof MainFragment == false) { getSupportFragmentManager().beginTransaction() .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) .replace(R.id.contentContainer, MainFragment.newInstance()) .addToBackStack(null) .commit(); } }
—
ลองทดสอบ Run App ดู เมื่อกด Hamberger Button จะมี Drawer Menu โผล่ออกมา
ต่อไปคือการสร้าง Custom Listview มีตัวอย่างทำไว้ในบทความที่แล้วเรื่อง How to create custom listview
อันดับแรกเรามา Design UI ของ ListView กันก่อน โดย New Layout กำหนดชื่อว่า Create news_list_item.xml พร้อมจัดให้มี ImageVew และ TextView ตามรูป หรือจะจัดยังไงก็ได้เอาที่สบายใจ 😛 แต่ขอให้มีรูปกับข้อความ เพราะเราจะไป Sync กับ Firebase
เพิ่มไลบรารี่ Glide เพื่อช่วยในการจัดการรูปภาพลงไปใน build.gradle
dependencies { compile 'com.github.bumptech.glide:glide:3.7.0' }
Create NewsListItem.java โดย extends จาก Class BaseCustomViewGroup (สามารถ download ได้จาก github) ทำการ findById Instance เพื่อผูก Instance กับ Layout และ สร้างเมธอด Set สำหรับ Adapter ต่อไป
public class NewsListItem extends BaseCustomViewGroup { private TextView tvHeader; private TextView tvDate; private TextView tvContent; private ImageView imgView; private TextView tvId; public NewsListItem(Context context) { super(context); initInflate(); initInstances(); } public NewsListItem(Context context, AttributeSet attrs) { super(context, attrs); initInflate(); initInstances(); initWithAttrs(attrs, 0, 0); } public NewsListItem(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initInflate(); initInstances(); initWithAttrs(attrs, defStyleAttr, 0); } @TargetApi(21) public NewsListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); initInflate(); initInstances(); initWithAttrs(attrs, defStyleAttr, defStyleRes); } private void initInflate() { inflate(getContext(), R.layout.news_list_item, this); } private void initInstances() { tvId = (TextView) findViewById(R.id.tvId); tvHeader = (TextView) findViewById(R.id.tvHeader); tvDate = (TextView) findViewById(R.id.tvDate); tvContent = (TextView) findViewById(R.id.tvContent); imgView = (ImageView) findViewById(R.id.imgView); } private void initWithAttrs(AttributeSet attrs, int defStyleAttr, int defStyleRes) { /* TypedArray a = getContext().getTheme().obtainStyledAttributes( attrs, R.styleable.StyleableName, defStyleAttr, defStyleRes); try { } finally { a.recycle(); } */ } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); BundleSavedState savedState = new BundleSavedState(superState); // Save Instance State(s) here to the 'savedState.getBundle()' // for example, // savedState.getBundle().putString("key", value); return savedState; } @Override protected void onRestoreInstanceState(Parcelable state) { BundleSavedState ss = (BundleSavedState) state; super.onRestoreInstanceState(ss.getSuperState()); Bundle bundle = ss.getBundle(); // Restore State from bundle here } public void setTvId(String text) { tvId.setText(text); } public void setTvHeader(String text) { tvHeader.setText(text); } public void setTvDate(String text) { tvDate.setText(text); } public void setTvContent(String text) { tvContent.setText(text); } public void setImgView(String path) { Glide.with(getContext()) .load(path) .placeholder(loading) .diskCacheStrategy(DiskCacheStrategy.ALL) // .skipMemoryCache(true) .into(imgView); } }
สร้างData Access Object ใช้ชื่อว่า NewsDao.java โดยกำหนดให้ implements เป็น Parcelable พร้อมทั้ง Generate Getter and Setter
public class NewsDao implements Parcelable { private String newsId; private String header; private String content; private String imagePath; private String date; public NewsDao() { } protected NewsDao(Parcel in) { newsId = in.readString(); header = in.readString(); content = in.readString(); imagePath = in.readString(); date = in.readString(); } public static final Creator<NewsDao> CREATOR = new Creator<NewsDao>() { @Override public NewsDao createFromParcel(Parcel in) { return new NewsDao(in); } @Override public NewsDao[] newArray(int size) { return new NewsDao[size]; } }; public String getNewsId() { return newsId; } public void setNewsId(String newsId) { this.newsId = newsId; } public String getHeader() { return header; } public void setHeader(String header) { this.header = header; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getImagePath() { return imagePath; } public void setImagePath(String imgPath) { this.imagePath = imgPath; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel parcel, int i) { parcel.writeString(newsId); parcel.writeString(header); parcel.writeString(content); parcel.writeString(imagePath); parcel.writeString(date); } }
สร้าง Adapter ใช้ชื่อว่า NewsAdapter.java โดย
1. เพิ่ม extends BaseAdapter จากนั้นก็ Auto Generate method
public class NewsAdapter extends BaseAdapter
2. สร้างฟิลด์ของคลาสด้วย NewsDao โดยกำหนดชนิดข้อมูลเป็น List เพื่อเก็บข้อมูลที่ดึงมาจาก Firebase
List<NewsDao> newsList;
3. ที่เมธอด getCount ส่งค่าขนาดของ Object ที่ดึงมาเก็บไว้ใน NewsList
public int getCount() { if (newsList == null) return 0; return newsList.size(); }
4. ที่เมธอด getView นำค่าที่เก็บไว้ใน newsList ส่งไปแสดงผลที่ NewsListItem ที่สร้างไว้
public View getView(int position, View view, ViewGroup viewGroup) { NewsListItem item; if (view != null) item = (NewsListItem) view; else item = new NewsListItem(viewGroup.getContext()); NewsDao dao = newsList.get(position); item.setTvId(dao.getNewsId()); item.setTvHeader(dao.getHeader()); item.setTvDate(dao.getDate()); item.setTvContent(dao.getContent()); item.setImgView(dao.getImgPath()); return item; }
NewsAdapter.java
public class NewsAdapter extends BaseAdapter { List<NewsDao> newsList; public NewsAdapter(List<NewsDao> newsList) { this.newsList = newsList; } @Override public int getCount() { if (newsList == null) return 0; return newsList.size(); } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int position, View view, ViewGroup viewGroup) { NewsListItem item; if (view != null) item = (NewsListItem) view; else item = new NewsListItem(viewGroup.getContext()); NewsDao dao = newsList.get(position); item.setTvId(dao.getNewsId()); item.setTvHeader(dao.getHeader()); item.setTvDate(dao.getDate()); item.setTvContent(dao.getContent()); item.setImgView(dao.getImgPath()); return item; } }
ติดตั้ง Firebase และ เพิ่ม Firebase ลงในโปรเจค ดูจากบทความ แนะนำการใช้งาน Firebase และสร้างแอป Android ติดต่อ Firebase Database
Add the dependency for Firebase Realtime Database to your app-level build.gradle
file:
compile 'com.google.firebase:firebase-database:11.0.1'
Add the dependency for Firebase Storage to your app-level build.gradle
file:
compile 'com.google.firebase:firebase-storage:11.0.1'
—
สร้างคลาส FirebaseConection.java
public class FirebaseConnection { public FirebaseConnection() { } public DatabaseReference getDatabase() { return FirebaseDatabase.getInstance().getReference(); } public DatabaseReference getDatabase(String string) { return FirebaseDatabase.getInstance().getReference().child(string); } public StorageReference getStorage() { return FirebaseStorage.getInstance().getReference(); } public StorageReference getStorage(String string) { return FirebaseStorage.getInstance().getReference().child(string); } }
—
กลับมาที่ MainFragment.java
สร้างเมธอด initInstances() เพื่อผูกกับ Object ใน Layer
private void initInstances(View rootView) { listView = (ListView) rootView.findViewById(R.id.listView); newsList = new ArrayList<>(); }
สร้างเมธอด showData() เพื่อทำการดึงข้อมูลมาจาก Firebase Database จากนั้นส่งไปแสดงใน ListView
private void showData(){ Query query = firebase.getDatabase("news"); query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { newsList.clear(); for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { NewsDao dao = postSnapshot.getValue(NewsDao.class); newsList.add(dao); } adapter = new NewsAdapter(newsList); listView.setAdapter(adapter); } @Override public void onCancelled(DatabaseError databaseError) { } }); }
เพิ่มเมธอด showData() ลงไปใน onCreateView เพื่อให้ดึงข้อมูลจาก firebase มาแสดงอัตโนมัติเมื่อเปิดหน้า MainFragment
เนื่องจากใน Realtime Database ยังไม่มีข้อมูล ในที่นี้ผมใช้ Postman ส่ง news.json Post เข้าไปยัง Firebase
เมื่อ Post สำเร็จ ใน Realtime Database ก็จะแสดงข้อมูล json ที่ส่งเข้าไป
ทดสอบ Run App ข้อมูลก็จะขึ้นที่ ListView
—
ขั้นต่อไปเราจะทำการสร้างหน้าเพิ่มข้อมูล โดยออกแบบดังนี้
1.ให้สามารถเพิ่มข้อมูลที่เป็น Text และ Image
2.มีปุ่ม Save , Update , Delete
สร้างไฟล์ Layout ที่ชื่อว่า fragment_add.xml
สร้างไฟล์ addFragment.java ตามโครงสร้าง และทำการ Inflate กับ Layout fragment_add.xml ให้เรียบร้อย
public class AddFragment extends Fragment { public AddFragment() { super(); } public static AddFragment newInstance() { AddFragment fragment = new AddFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_add, container, false); initInstances(rootView); return rootView; } private void initInstances(View rootView) { // Init 'View' instance(s) with rootView.findViewById here } @Override public void onStart() { super.onStart(); } @Override public void onStop() { super.onStop(); } /* * Save Instance State Here */ @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save Instance State here } /* * Restore Instance State Here */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (savedInstanceState != null) { // Restore Instance State here } } }
—
สร้าง Layout Activity ชื่อ activity_add.xml และเพิ่ม FramLayout เพื่อรอ Fragment มาแปะ
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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" tools:context="com.tntadvance.testfirebasecrud.activity.AddActivity"> <FrameLayout android:id="@+id/contentContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
—
เลือก New->Activity->Empty Activity
ตั้งชื่อว่า AddActivity จะได้ไฟล์ addActivity.java และ activity_add.xml
ที่ไฟล์ activity_add.xml ให้เพิ่ม FramLayout และตั้ง id เป็น ContentContainer เพื่อรอ Fragment มาแปะ
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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" tools:context="com.tntadvance.testfirebasecrud.activity.AddActivity"> <FrameLayout android:id="@+id/contentContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
—
ที่ไฟล์ AddActivity.java
1.สร้างเมธอด initFragment() เพื่อสั่งให้ AddFragment มาแปะบน ContentContainer
private void initFragment(Bundle savedInstanceState, NewsDao dao) { if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.contentContainer, AddFragment.newInstance(dao)) .commit(); } }
2.สร้างเมธอด initInstance เพื่อเพิ่มปุ่ม Up Button
private void initInstances() { getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); }
AddActivity.java
public class AddActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add); initInstances(); initFragment(savedInstanceState); } private void initInstances() { getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); } private void initFragment(Bundle savedInstanceState) { if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.contentContainer, AddFragment.newInstance()) .commit(); } } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home){ finish(); return true; } return super.onOptionsItemSelected(item); } }
—
ต่อไปเป็นการเพิ่มคำสั่งที่ให้ปุ่ม Floating Action เปิดหน้าเพิ่มข้อมูล
เนื่องจากปุ่มอยู่ใน MainFragment ซึ่งแปะอยู่บน MainActivity แต่ AddFragment ที่ต้องการเปิดจะแปะอยู่บน AddActivity เราจึงต้องทำดังนี้
1. Implement Interface FragmentListener บน MainFragment.java พร้อมสร้างเมธอด openAddFragment() เพื่อไปเรียกใช้ onItemListClicked บน MainActivity พร้อมส่ง NewsDao แนบไปด้วย
//implement interface public interface FragmentListener { void onItemListClicked(NewsDao dao); } private void openAddFragment(){ NewsDao dao = new NewsDao(); FragmentListener listener = (FragmentListener) getActivity(); listener.onItemListClicked(dao); }
—
2.Implement FragmentListener in MainActivity
สร้างเมธอดจาก Interface คือ onItemListClicked เพื่อสั่ง Intent ให้เปิด AddActivity พร้อมแนบ NewsDao ไปด้วย
@Override public void onItemListClicked(NewsDao dao) { Intent intent = new Intent(MainActivity.this,AddActivity.class); intent.putExtra("dao",dao); startActivity(intent); }
—
3.เพิ่มคำสั่ง getIntent() ที่ AddActivity.java เพื่อรับค่า NewsDao
NewsDao dao = getIntent().getParcelableExtra("dao");
และส่ง NewsDao ต่อไปเปิดใน AddFragment
initFragment(savedInstanceState, dao);
private void initFragment(Bundle savedInstanceState, NewsDao dao) { if (savedInstanceState == null) { getSupportFragmentManager().beginTransaction() .add(R.id.contentContainer, AddFragment.newInstance(dao)) .commit(); } }
—
เปิด AddFragment.java เพิ่มการรับค่า NewsDao
รับค่า NewsDao ที่เมธอด onCreate
—
Test Run App
ทดสอบ Click ปุ่มเพิ่มข้อมูลจะเปิดหน้าเพิ่มข้อมูลขึ้นมา จากนั้น Click Up Button เพื่อกลับหน้าหลัก
—
เนื่องจากตอน Clck ปุ่มเพิ่มข้อมูล NewsDao จะไม่มีข้อมูลจึงเปิดหน้าว่างขึ้นมา
ขั้นต่อไปเราจะมาทำเมื่อ Click ที่ Listview ให้ส่งข้อมูลไปยัง AddFragment เพื่อแก้ไขข้อมูล
ที่ไฟล์ MainFragment เพิ่ม setOnClickListener ให้กับ Listview
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { NewsDao dao = newsList.get(i); FragmentListener listener = (FragmentListener) getActivity(); listener.onItemListClicked(dao); } });
—
นำข้อมูลที่เก็บไว้ใน NewsDao มาใส่ที่ Object และเช็คก่ีแสดงผลให้ปุ่ม Save , Update ,Delete
private void checkData(){ dao = getArguments().getParcelable("dao"); id = dao.getNewsId(); header = dao.getHeader(); content = dao.getContent(); path = dao.getImagePath(); if (!TextUtils.isEmpty(header)) { getActivity().setTitle(header); edHeader.setText(header); edContent.setText(content); tvPath.setText(path); Glide.with(getContext()) .load(path) .placeholder(default1) .diskCacheStrategy(DiskCacheStrategy.ALL) // .skipMemoryCache(true) .into(imgView); btnSave.setVisibility(View.GONE); btnUpdate.setVisibility(View.VISIBLE); btnDelete.setVisibility(View.VISIBLE); } else { btnSave.setVisibility(View.VISIBLE); btnUpdate.setVisibility(View.GONE); btnDelete.setVisibility(View.GONE); } }
—
ทดสอบ Run App เมื่อกดที่ Listview จะเปิด AddFragment โดยมีข้อมูลแสดที่หน้าจอ
—
—
ต่อไปเป็นการเพิ่มรูปโดยการถ่ายรูปหรือเลือกรูปจาก
(ตัวอย่าง Code : https://github.com/thana19/testCamera )
เพิ่มเมธอด addImage ที่ AddFragment.java ดังนี้
private void addImage() { final String[] items = new String[]{"Take from camera", "Select from gallery"}; ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle("Select Image"); builder.setAdapter(adapter, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { //pick from camera if (item == 0) { Log.d("camera", "camera"); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); try { intent.putExtra("return-data", true); startActivityForResult(intent, PICK_FROM_CAMERA); } catch (ActivityNotFoundException e) { e.printStackTrace(); } } else { //pick from file if (Build.VERSION.SDK_INT < 19) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE); } else { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE); } } } }); final AlertDialog dialog = builder.create(); dialog.show(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != -1) return; switch (requestCode) { case PICK_FROM_CAMERA: mImageCaptureUri = data.getData(); doCrop(); break; case PICK_FROM_FILE: mImageCaptureUri = data.getData(); doCrop(); break; case CROP_FROM_CAMERA: Bundle extras = data.getExtras(); if (extras != null) { bitmapCrop = extras.getParcelable("data"); imgView.setImageBitmap(bitmapCrop); } break; } } private void doCrop() { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setType("image/*"); List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities(intent, 0); int size = list.size(); if (size == 0) { Toast.makeText(getActivity(), "Can not find image crop app", Toast.LENGTH_SHORT).show(); } else { intent.setData(mImageCaptureUri); intent.putExtra("outputX", 600); intent.putExtra("outputY", 600); intent.putExtra("aspectX", 6); intent.putExtra("aspectY", 6); intent.putExtra("scale", true); intent.putExtra("return-data", true); Intent i = new Intent(intent); ResolveInfo res = list.get(0); i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name)); startActivityForResult(i, CROP_FROM_CAMERA); } }
—
เพิ่มข้อมูลไปยัง Firebase Realtime Database & Storage
private void addData() { id = firebase.getDatabase("news").push().getKey(); header = edHeader.getText().toString(); content = edContent.getText().toString(); NewsDao dao = new NewsDao(); dao.setNewsId(id); dao.setHeader(header); dao.setContent(content); dao.setDate(dateUtil.currentTimeStamp()); uploadFromDataInMemory(dao); } private void uploadFromDataInMemory(final NewsDao dao) { // Get the data from an ImageView as bytes imgView.setDrawingCacheEnabled(true); imgView.buildDrawingCache(); Bitmap bitmap = imgView.getDrawingCache(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] data = baos.toByteArray(); UploadTask uploadTask = firebase.getStorage("news/" + id + "/" + dateUtil.currentTimeStamp() + ".png").putBytes(data); uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { @Override public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { @SuppressWarnings("VisibleForTests") double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount(); Log.d("progress", "Upload is " + progress + "% done"); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { } }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { @SuppressWarnings("VisibleForTests") Uri downloadUrl = taskSnapshot.getDownloadUrl(); tvPath.setText(downloadUrl.toString()); dao.setImagePath(downloadUrl.toString()); firebase.getDatabase("news").child(id).setValue(dao); Toast.makeText(getActivity(), "Upload Complete", Toast.LENGTH_LONG).show(); getActivity().finish(); } }); }
ลบข้อมูล
private void deleteData() { //removing firebase.getDatabase("news").child(id).removeValue(); getActivity().finish(); Toast.makeText(getActivity(), "ANews Deleted", Toast.LENGTH_LONG).show(); }
Update ข้อมูล
private void updateData() { if (bitmapCrop != null) { NewsDao dao = new NewsDao(); dao.setNewsId(id); dao.setHeader(header); dao.setContent(content); dao.setDate(dateUtil.currentTimeStamp()); uploadFromDataInMemory(dao); } else { Toast.makeText(getActivity(), "Do not change image", Toast.LENGTH_LONG).show(); HashMap<String, Object> postValues = new HashMap<>(); postValues.put("header", edHeader.getText().toString()); postValues.put("content", edContent.getText().toString()); firebase.getDatabase("news").child(id).updateChildren(postValues); getActivity().finish(); } }
—
หลังๆไม่รู้จะอธิบายยังไง จริงๆขี้เกียจแล้ว 55555 ก็ขอตัดจบเพียงเท่านี้นะครับ สวัสดี
* ถ้าว่างๆจะกลับมา update เนื้อหาในส่วน firebase นะครับ
—
ตัวอย่าง code สามารถดาวน์โหลดไปแกะเล่นได้ที่ : https://github.com/thana19/FirebaseNews