build.gradle (Module: app)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.phaisarn.myapplication" minSdkVersion 21 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.android.support:cardview-v7:26.1.0' } |
layout/custom_layout.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" app:cardBackgroundColor="#fafafa" app:cardCornerRadius="10dp" app:cardElevation="3dp"> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="2" android:padding="10dp"> <ImageView android:id="@+id/imageView" android:layout_width="45dp" android:layout_height="45dp" android:layout_marginRight="15dp" android:layout_marginTop="5dp" android:layout_rowSpan="3" /> <GridLayout android:layout_columnWeight="1" android:layout_marginBottom="5dp"> <TextView android:id="@+id/textView_name" android:maxLines="1" android:maxWidth="170dp" android:textColor="#900" android:textSize="20sp" /> <TextView android:id="@+id/textView_phone" android:layout_columnWeight="1" android:gravity="right" android:textColor="#090" android:textSize="18sp" /> </GridLayout> <TextView android:layout_height="2dp" android:layout_columnWeight="1" android:layout_marginBottom="10dp" android:background="#bbb" /> <GridLayout android:layout_columnWeight="1"> <TextView android:id="@+id/textView_delete" android:layout_marginRight="10dp" android:drawablePadding="8dp" android:text="ลบ" android:textColor="#009" android:textSize="16sp" /> <TextView android:id="@+id/textView_edit" android:layout_width="wrap_content" android:layout_marginLeft="10dp" android:drawablePadding="8dp" android:text="แก้ไข" android:textColor="#009" android:textSize="16sp" /> <Space android:layout_columnWeight="1" /> <TextView android:id="@+id/textView_call" android:drawableLeft="@drawable/up" android:drawablePadding="8dp" android:gravity="right" android:text="โทรออก" android:textColor="#009" android:textSize="16sp" /> </GridLayout> </GridLayout> </android.support.v7.widget.CardView> |
layout/dialog_layout.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="2" android:padding="20dp" android:rowCount="3"> <TextView android:gravity="right" android:text="ชื่อ:" android:textSize="20sp" /> <EditText android:id="@+id/dialog_name" android:layout_width="220dp" android:layout_marginLeft="10dp" android:textSize="20sp" /> <Space android:layout_height="10dp" android:layout_columnSpan="2" /> <TextView android:text="เบอร์โทร:" android:textSize="20sp" /> <EditText android:id="@+id/dialog_num" android:layout_width="220dp" android:layout_marginLeft="10dp" android:textSize="20sp" /> </GridLayout> |
content_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?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" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/content_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#cde" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context=".MainActivity" tools:showIn="@layout/activity_main"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.v7.widget.RecyclerView> </LinearLayout> |
ConfirmDialog.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
package com.phaisarn.myapplication; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; public class ConfirmDialog extends DialogFragment { /* ควรสร้างตัวเลือกแบบ enum สำหรับใช้เปรียบเทียบว่าปุ่มใดถูกคลิก จะช่วยลดข้อผิดพลาดได้มากกว่าการใช้ค่าเป็นสตริง */ enum Button { //จะอ้างถึง enum นี้ในแบบ ConfirmDialog.Button Negative, Positive } public ConfirmDialog() { } public static ConfirmDialog newInstance( String msg, String negText, String posText) { ConfirmDialog dialog = new ConfirmDialog(); Bundle args = new Bundle(); args.putString("message", msg); args.putString("negText", negText); args.putString("posText", posText); dialog.setArguments(args); return dialog; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { String message = getArguments().getString("message"); String posText = getArguments().getString("posText"); String negText = getArguments().getString("negText"); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) .setMessage(message) .setNegativeButton(negText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { mListener.onFinishDialog(ConfirmDialog.Button.Negative); } }) .setPositiveButton(posText, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { mListener.onFinishDialog(ConfirmDialog.Button.Positive); } }); return builder.create(); } interface OnFinishDialogListener { void onFinishDialog(ConfirmDialog.Button button); //กำหนด Type ของพารามิเตอร์เป็น enum ที่สร้างขึ้น } private OnFinishDialogListener mListener; public void setOnFinishDialogListener(OnFinishDialogListener listener) { mListener = listener; } } |
CustomAdapter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
package com.phaisarn.myapplication; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.amulyakhare.textdrawable.TextDrawable; import com.amulyakhare.textdrawable.util.ColorGenerator; import java.util.List; public class CustomAdapter extends RecyclerView.Adapter<CustomHolder> { private Context mContext; private List<CustomItem> mItems; public interface OnTextClickListener { void onTextClick(View v, int pos); } private OnTextClickListener mListener; public void setOnTextClickListener(OnTextClickListener listener) { mListener = listener; } public CustomAdapter(Context context, List<CustomItem> items) { mContext = context; mItems = items; } @Override public CustomHolder onCreateViewHolder(ViewGroup parent, int position) { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.custom_layout, parent, false); return new CustomHolder(view); } @Override public void onBindViewHolder(final CustomHolder vHolder, final int pos) { final CustomItem item = mItems.get(pos); String letter = String.valueOf(item.name.charAt(0)); ColorGenerator generator = ColorGenerator.MATERIAL; TextDrawable drawable = TextDrawable.builder() .buildRoundRect(letter, generator.getRandomColor(), 30); vHolder.imageView.setImageDrawable(drawable); vHolder.textName.setText(item.name); vHolder.textPhone.setText(item.phoneNum); vHolder.textDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int p = vHolder.getAdapterPosition(); if (p != RecyclerView.NO_POSITION) { mListener.onTextClick(v, p); } } }); vHolder.textEdit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //String str = "ให้สร้าง Custom Dialog เพื่อรับข้อมูลมาแก้ไขค่าเดิม เหมือนที่เคยทำกับ ListView"; //new AlertDialog.Builder(mContext).setMessage(str).show(); int p = vHolder.getAdapterPosition(); if (p != RecyclerView.NO_POSITION) { mListener.onTextClick(v, p); } } }); vHolder.textCall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String phone = item.phoneNum; Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData((Uri.parse("tel:" + phone))); try { mContext.startActivity(intent); } catch (SecurityException ex) { } } }); } @Override public int getItemCount() { return mItems.size(); } } |
CustomItem.java
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.phaisarn.myapplication; public class CustomItem { public String name; public String phoneNum; public CustomItem(String name, String phoneNum) { this.name = name; this.phoneNum = phoneNum; } } |
InputDialog.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
package com.phaisarn.myapplication; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.view.View; import android.widget.EditText; public class InputDialog extends DialogFragment { public InputDialog() { } //empty constructor public static InputDialog newInstance(String title, String defName, String defNum) { InputDialog dialog = new InputDialog(); Bundle args = new Bundle(); args.putString("title", title); args.putString("name", defName); args.putString("num", defNum); dialog.setArguments(args); return dialog; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { View v = getActivity().getLayoutInflater().inflate( R.layout.dialog_layout, null); String title = getArguments().getString("title"); String name = getArguments().getString("name"); String num = getArguments().getString("num"); final EditText editName = (EditText) v.findViewById(R.id.dialog_name); editName.setText(name); final EditText editNum = (EditText) v.findViewById(R.id.dialog_num); editNum.setText(num); AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()) .setTitle(title) .setView(v) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { dialog.dismiss(); } }) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { mListener.onFinishDialog(editName.getText().toString(), editNum.getText().toString()); } }); return alertDialogBuilder.create(); } interface OnFinishDialogListener { void onFinishDialog(String name, String num); } private OnFinishDialogListener mListener; public void setOnFinishDialogListener(OnFinishDialogListener listener) { mListener = listener; } } |
CustomHolder.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.phaisarn.myapplication; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.ImageView; import android.widget.TextView; public class CustomHolder extends RecyclerView.ViewHolder { public ImageView imageView; public TextView textName; public TextView textPhone; public TextView textDelete; public TextView textEdit; public TextView textCall; public CustomHolder(View view) { super(view); imageView = (ImageView) view.findViewById(R.id.imageView); textName = (TextView) view.findViewById(R.id.textView_name); textPhone = (TextView) view.findViewById(R.id.textView_phone); textDelete = (TextView) view.findViewById(R.id.textView_delete); textEdit = (TextView) view.findViewById(R.id.textView_edit); textCall = (TextView) view.findViewById(R.id.textView_call); } } |
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
package com.phaisarn.myapplication; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.support.v4.app.FragmentManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import java.util.ArrayList; import java.util.Arrays; public class MainActivity extends AppCompatActivity { private final int ADD = 0; private final int EDIT = 1; private ArrayList<CustomItem> mItemArray; private CustomAdapter mAdapter; private RecyclerView mRcv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mItemArray = new ArrayList<>(); mItemArray.addAll(Arrays.asList( new CustomItem("มานี", "099111xxxx"), new CustomItem("มานะ", "099222xxxx"), new CustomItem("ปิติ", "099333xxxx"), new CustomItem("วีระ", "099444xxxx"), new CustomItem("ชูใจ", "099555xxxx"), new CustomItem("ครูไพลิน", "099666xxxx"))); mRcv = (RecyclerView) findViewById(R.id.recyclerView); mAdapter = new CustomAdapter(this, mItemArray); mRcv.setAdapter(mAdapter); mRcv.setLayoutManager(new LinearLayoutManager(this)); mAdapter.setOnTextClickListener(new CustomAdapter.OnTextClickListener() { @Override public void onTextClick(View v, int pos) { if (v.getId() == R.id.textView_delete) { showConfirmDialog(pos); } else if (v.getId() == R.id.textView_edit) { String na = mItemArray.get(pos).name; String no = mItemArray.get(pos).phoneNum; showInputDialog(na, no, EDIT, pos); } } }); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) // .setAction("Action", null).show(); //mItemArray.add(new CustomItem("ใหม่", "098765xxxx")); //mAdapter.notifyItemInserted(mItemArray.size() - 1); //rcv.scrollToPosition(mItemArray.size() - 1); showInputDialog("", "", ADD, 0); } }); } private void showConfirmDialog(final int position) { FragmentManager fm = getSupportFragmentManager(); ConfirmDialog dlg = ConfirmDialog.newInstance( "ท่านต้องการลบรายการนี้จริงหรือไม่?", "ไม่ใช่", "ใช่"); //negative, positive dlg.show(fm, null); dlg.setOnFinishDialogListener( new ConfirmDialog.OnFinishDialogListener() { @Override public void onFinishDialog(ConfirmDialog.Button button) { if (button == ConfirmDialog.Button.Positive) { mItemArray.remove(position); mAdapter.notifyItemRemoved(position); } } }); } private void showInputDialog(String defaultName, String defaultNum, final int type, final int pos) { FragmentManager fm = getSupportFragmentManager(); InputDialog dialog = InputDialog.newInstance("ชื่อและเบอร์โทร", defaultName, defaultNum); dialog.show(fm, null); dialog.setOnFinishDialogListener( new InputDialog.OnFinishDialogListener() { @Override public void onFinishDialog(String name, String num) { if (name.trim().isEmpty() || num.trim().isEmpty()) { return; } if (type == ADD) { mItemArray.add(new CustomItem(name, num)); mAdapter.notifyItemInserted(mItemArray.size() - 1); mRcv.scrollToPosition(mItemArray.size() - 1); } else if (type == EDIT) { mItemArray.set(pos, new CustomItem(name, num)); mAdapter.notifyItemChanged(pos); } } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds mItemArray to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } |
รูปที่ใช้