[Android] JSon trong Android – Phần 4: Xử lý lấy JSon bằng Java
Hế lô các bạn, Dự đây sẽ là phần cuối trong loạt bài JSon trong Android. Chúng ta sẽ viết nốt code java xử lý và quan trọng nhất là lấy JSon mà chúng ta đã xuất ra từ các phần trước.
Nội dung
Update: 21/08/2015 – Tối ưu hóa code.
Cấu trúc java của chúng ta gồm các file sau (Do số lượng file ít nên mình không có phân thành các package).
Viết các class cấu hình, chuẩn bị
Nói nó hơi khó hiểu nhưng thật ra là thế này. Chúng ta cần một số hằng số để lưu một số giá trị nhất định và nó nằm trong class Var. Để thao tác dễ dàng với các đối tượng “người yêu cũ” thì chúng ta cần có một class Lover. Và để lấy JSon xuống thì chúng ta cần class LoadJson làm việc đó.
Xây dựng các hằng số
package cachhoc.net.demojson; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.widget.Toast; public class Var { // const for load and put data with server public static final String KEY_METHOD = "method"; public static final String KEY_NICK = "nick"; public static final String KEY_PASS = "pass"; public static final String KEY_ID = "id"; public static final String KEY_NAME = "name"; public static final String KEY_PHONE = "phone"; public static final String KEY_BEGIN_DATE = "begin_date"; public static final String KEY_END_DATE = "end_date"; public static final String KEY_LOGIN = "login"; public static final String KEY_REGISTER = "register"; public static final String KEY_ADD = "add"; public static final int METHOD_LOGIN = 1; public static final int METHOD_REGISTER = 2; public static final int METHOD_GET_OLD_LOVER = 3; public static final int METHOD_ADD_OLD_LOVER = 4; public static void showToast(Context context, String sms) { Toast.makeText(context, sms, Toast.LENGTH_SHORT).show(); } // method for save and get nick and pass user public static void save(Context context, String key, String value) { SharedPreferences.Editor editor = PreferenceManager .getDefaultSharedPreferences(context.getApplicationContext()) .edit(); editor.putString(key, value); editor.apply(); } public static String get(Context context, String key) { SharedPreferences settings = PreferenceManager .getDefaultSharedPreferences(context.getApplicationContext()); return settings.getString(key, null); } }
Không có gì là khó hiểu, trong class này mình chỉ lưu ý là chúng ta sử dụng SharedPreferences để lưu trữ nick và pass khi người dùng muốn ghi nhớ cho lần đăng nhập sau. Và nó cũng thường dùng để lưu các cài đặt (setting) cho các ứng dụng.
Xây dựng class Lover
Lover của chúng ta sẽ có 5 trường chính là id, name, phone, begin date (ngày bắt đầu yêu) và end date (ngày chia tay).
package cachhoc.net.demojson; import org.json.JSONException; import org.json.JSONObject; public class Lover { private int id; private String name; private String phone; private String beginDate; private String endDate; public Lover() { } public Lover(int id, String name, String phone, String beginDate, String endDate) { this.id = id; this.name = name; this.phone = phone; this.beginDate = beginDate; this.endDate = endDate; } public int getId() { return id; } public Lover setId(int id) { this.id = id; return this; } public String getName() { return name; } public Lover setName(String name) { this.name = name; return this; } public String getPhone() { return phone; } public Lover setPhone(String phone) { this.phone = phone; return this; } public String getBeginDate() { return beginDate; } public Lover setBeginDate(String beginDate) { this.beginDate = beginDate; return this; } public String getEndDate() { return endDate; } public Lover setEndDate(String endDate) { this.endDate = endDate; return this; } public String toJSON() { JSONObject jsonObject = new JSONObject(); try { jsonObject.put(Var.KEY_ID, getId()); jsonObject.put(Var.KEY_NAME, getName()); jsonObject.put(Var.KEY_PHONE, getPhone()); jsonObject.put(Var.KEY_BEGIN_DATE, getBeginDate()); jsonObject.put(Var.KEY_END_DATE, getEndDate()); return jsonObject.toString(); } catch (JSONException e) { e.printStackTrace(); return ""; } } }
Các bạn chú ý thông thường các phương thức getter chúng ta không trả về giá trị gì và thường là public void… tuy nhiên mình viết chúng trả về chính đối tượng Lover (return this). Điều này giúp cho chúng ta thao tác dễ hơn. Ví dụ như khi các bạn muốn set 2 giá trị name và phone thì các bạn phải viết 2 lần là lover.setName và lover.setPhone như thế có thể làm máy chạy chậm hơn giống như khi bạn đi chợ, bạn mua rau rồi chạy về, rồi lại chạy ra mua đậu,… Còn mình chỉ cần lover.setName(…).setPhone(…) tức là đi chợ mua rau và mua luôn cả đậu. =))
Phương thức toJSON mình viết để chuyển 1 đối tượng sang dạng JSon để dễ dàng cho các thao tác gửi dữ liệu lên server, tuy nhiên trong App này thì mình không dùng nó, viết để các bạn biết và có thể dùng cho các app khác thôi.
Xây dựng class LoadJSon
Thực ra trong này không chỉ lấy JSon về mà còn gửi dữ liệu lên để xử lý nữa. Và như hôm trước khi xây dựng file lover.php mình có nói là chúng ta phân biệt các hành động thông qua biến method.
package cachhoc.net.demojson; import com.loopj.android.http.AsyncHttpClient; import com.loopj.android.http.AsyncHttpResponseHandler; import com.loopj.android.http.RequestParams; import org.apache.http.Header; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.HashMap; public class LoadJson { public static final String LINK = "https://cachhoc.net/mobile/demo-json/lover.php"; public void sendDataToServer(int method, HashMap<String, String> map) { AsyncHttpClient client = new AsyncHttpClient(); RequestParams params = new RequestParams(); // put data to server params.put(Var.KEY_METHOD, method); if (map != null) { for (String key : map.keySet()) { params.put(key, map.get(key)); } } System.out.println("Post..."); client.post(LINK, params, new AsyncHttpResponseHandler() { @SuppressWarnings("deprecation") @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { String json = new String(responseBody); System.out.println("onSuccess:" + json); onFinishLoadJSonListener.finishLoadJSon(null, json); } @SuppressWarnings("deprecation") @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { System.out.println("onFailure:" + statusCode); String e; if (statusCode == 404) { e = "Requested resource not found"; } else if (statusCode == 500) { e = "Something went wrong at server end"; } else { e = "Device might not be connected to Internet"; } onFinishLoadJSonListener.finishLoadJSon(e, null); } }); } public static Lover jsonToLover(JSONObject jsonObject) { try { int id = jsonObject.getInt(Var.KEY_ID); String name = jsonObject.getString(Var.KEY_NAME); String phone = jsonObject.getString(Var.KEY_PHONE); String beginDate = jsonObject.getString(Var.KEY_BEGIN_DATE); String endDate = jsonObject.getString(Var.KEY_END_DATE); return new Lover(id, name, phone, beginDate, endDate); } catch (JSONException e) { e.printStackTrace(); return null; } } public static ArrayList<Lover> jsonToListLover(String json) { ArrayList<Lover> list = new ArrayList<>(); try { JSONArray arraySMSJson = new JSONArray(json); for (int i = 0; i < arraySMSJson.length(); i++) { JSONObject jsonObject = arraySMSJson.getJSONObject(i); Lover lover = jsonToLover(jsonObject); if (lover != null) { list.add(lover); } } } catch (JSONException e) { e.printStackTrace(); } return list; } public interface OnFinishLoadJSonListener { void finishLoadJSon(String error, String json); } public OnFinishLoadJSonListener onFinishLoadJSonListener; public void setOnFinishLoadJSonListener(OnFinishLoadJSonListener onFinishLoadJSonListener) { this.onFinishLoadJSonListener = onFinishLoadJSonListener; } }
Trong đó:
- Hằng số LINK là đường dẫn đến file xuất JSon – file lover.php đã xây dựng hôm trước.
-
Phương thức sendDataToServer có 2 đối số là method để phân biệt hành động (login, register, load json, add lover) để file lover.php trên server phân biệt xử lý. Biến HashMap<String, String> map là một danh sách các cặp key-value để chúng ta đưa dữ liệu lên, trên server sẽ dựa vào các key để lấy value tương ứng.
-
Khi chúng ta gọi client.post() thì hệ thông sẽ thực hiện chạy ngầm để gửi dữ liệu lên server. Khi kết thúc thì hệ thống sẽ tự động gọi phương thức onSuccess (thành công) hoặc onFailure (có lỗi) và trả về các giá trị tuơng ứng. Trong phương thức onSuccess thì responseBody chính là Json chúng ta lấy được về, nó ở dạng byte và ta cần chuyển sang dạng string.
-
Để lấy được JSon và phục vụ cho các class khác xử lý, chúng ta xây dựng một interface là OnFinishLoadJSonListener có phương thức finishLoadJSon(String error, String json) để các class khác implements lấy JSon hoặc lỗi để xử lý tiếp sau đó.
-
Trong này mình cũng xây dựn 2 phương thức jsonToLover và jsonToListLover để chuyển đổi chuỗi json về đối tượng Lover hoặc danh sách Lover.
Đến đây nghe vẻ hơi dài dài rồi. Phần quan trọng nhất là lấy JSon đã ổn. Chúng ta tiếp tục xử lý 4 Activity.
Xử lý các Activity
Tương tự như phần giao diện, chúng ta sẽ đi làm lần lượt các bước:
Cấu hình, Chuẩn bị -> Login -> Register -> List Old Lover -> Add Lover
Và trong code mình cũng đặt tên các phương thức khá rõ ràng nên sẽ không cần giải thích nhiều.
Activity Login
Để login vào được thì chúng ta sẽ phải gửi nick và pass lên hệ thông kiểm tra, file lover.php sẽ kiểm tra và nếu đúng thì mới login vào được.
package cachhoc.net.demojson; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; public class LoginActivity extends AppCompatActivity implements View.OnClickListener, LoadJson.OnFinishLoadJSonListener { private EditText editNick, editPass; private CheckBox cbRememberPass; private LoadJson loadJson; private Context context; private ProgressDialog progressDialog; private String nick, pass; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); context = this; setupToolbar(); connectView(); loadJson = new LoadJson(); loadJson.setOnFinishLoadJSonListener(this); progressDialog = new ProgressDialog(context); progressDialog.setMessage(context.getResources().getString(R.string.wait)); } private void setupToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setTitle(R.string.login); } } } private void connectView() { editNick = (EditText) findViewById(R.id.edit_nick); editPass = (EditText) findViewById(R.id.edit_pass); cbRememberPass = (CheckBox) findViewById(R.id.cb_remember); findViewById(R.id.btn_login).setOnClickListener(this); findViewById(R.id.btn_register).setOnClickListener(this); // get nick and pass if it be remember nick = Var.get(context, Var.KEY_NICK); pass = Var.get(context, Var.KEY_PASS); if (nick != null && pass != null) { editNick.setText(nick); editPass.setText(pass); cbRememberPass.setChecked(true); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_login: login(); break; case R.id.btn_register: register(); break; default: break; } } private void register() { Intent intent = new Intent(context, RegisterActivity.class); startActivity(intent); } private void login() { nick = editNick.getText().toString().trim(); pass = editPass.getText().toString().trim(); // not enter nick name if (nick.length() == 0) { editNick.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_nick)); return; } // not enter pass if (pass.length() == 0) { editPass.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_pass)); return; } // save nick and pass if (cbRememberPass.isChecked()) { Var.save(context, Var.KEY_NICK, nick); Var.save(context, Var.KEY_PASS, pass); } else { Var.save(context, Var.KEY_NICK, null); Var.save(context, Var.KEY_PASS, null); } HashMap<String, String> map = new HashMap<>(); map.put(Var.KEY_NICK, nick); map.put(Var.KEY_PASS, pass); loadJson.sendDataToServer(Var.METHOD_LOGIN, map); progressDialog.show(); } @Override public void finishLoadJSon(String error, String json) { if (progressDialog.isShowing()) { progressDialog.hide(); } try { if (json != null) { JSONObject jsonObject = new JSONObject(json); if (jsonObject.getBoolean(Var.KEY_LOGIN)) { Var.showToast(context, context.getResources().getString(R.string.login_success)); Intent intent = new Intent(context, MainActivity.class); intent.putExtra(Var.KEY_NICK, nick); startActivity(intent); finish(); } else { Var.showToast(context, context.getResources().getString(R.string.login_fail)); } } else { Var.showToast(context, error); } } catch (JSONException e) { e.printStackTrace(); } } }
Activity Register
Nếu chưa có tài khoản, chúng ta cần phải đăng ký để hệ thông thêm vào database.
package cachhoc.net.demojson; import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.EditText; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; public class RegisterActivity extends AppCompatActivity implements View.OnClickListener, LoadJson.OnFinishLoadJSonListener { private EditText editNick, editPass, editRePass; private LoadJson loadJson; private Context context; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); context = this; setupToolbar(); connectView(); loadJson = new LoadJson(); loadJson.setOnFinishLoadJSonListener(this); progressDialog = new ProgressDialog(context); progressDialog.setMessage(context.getResources().getString(R.string.wait)); } private void setupToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setTitle(R.string.register); } } } private void connectView() { editNick = (EditText) findViewById(R.id.edit_nick); editPass = (EditText) findViewById(R.id.edit_pass); editRePass = (EditText) findViewById(R.id.edit_re_pass); findViewById(R.id.btn_reset).setOnClickListener(this); findViewById(R.id.btn_register).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_reset: reset(); break; case R.id.btn_register: register(); break; default: break; } } private void reset() { editNick.setText(""); editPass.setText(""); editRePass.setText(""); editNick.requestFocus(); } private void register() { String nick = editNick.getText().toString().trim(); String pass = editPass.getText().toString().trim(); String repass = editRePass.getText().toString().trim(); // not enter nick name if (nick.length() == 0) { editNick.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_nick)); return; } // not enter pass if (pass.length() == 0) { editPass.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_pass)); return; } // not enter pass if (repass.length() == 0) { editRePass.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_repass)); return; } if (!repass.equals(pass)) { editPass.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.pass_not_match)); return; } HashMap<String, String> map = new HashMap<>(); map.put(Var.KEY_NICK, nick); map.put(Var.KEY_PASS, pass); loadJson.sendDataToServer(Var.METHOD_REGISTER, map); progressDialog.show(); } @Override public void finishLoadJSon(String error, String json) { if (progressDialog.isShowing()) { progressDialog.hide(); } try { if (json != null) { JSONObject jsonObject = new JSONObject(json); if (jsonObject.getBoolean(Var.KEY_REGISTER)) { Var.showToast(context, context.getResources().getString(R.string.register_success)); finish(); } else { Var.showToast(context, context.getResources().getString(R.string.register_fail)); } } else { Var.showToast(context, error); } } catch (JSONException e) { e.printStackTrace(); } } }
Activity Add Lover
package cachhoc.net.demojson; import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Button; import android.widget.EditText; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; import org.json.JSONException; import org.json.JSONObject; import java.util.Calendar; import java.util.HashMap; public class AddLoverActivity extends AppCompatActivity implements View.OnClickListener, LoadJson.OnFinishLoadJSonListener, DatePickerDialog.OnDateSetListener { private EditText editName, editPhone; private Button btnBeginDate, btnEndDate; private LoadJson loadJson; private Context context; private ProgressDialog progressDialog; private String nick; // for begin date or end date private int typeDate; private String beginDate = "", endDate = ""; public static final int BEGIN_DATE = 0; public static final int END_DATE = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_lover); context = this; setupToolbar(); connectView(); loadJson = new LoadJson(); loadJson.setOnFinishLoadJSonListener(this); progressDialog = new ProgressDialog(context); progressDialog.setMessage(context.getResources().getString(R.string.wait)); nick = getIntent().getStringExtra(Var.KEY_NICK); } private void setupToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); if (getSupportActionBar() != null) { getSupportActionBar().setTitle(R.string.title_activity_add_lover); } } } private void connectView() { editName = (EditText) findViewById(R.id.edit_name); editPhone = (EditText) findViewById(R.id.edit_phone); btnBeginDate = (Button) findViewById(R.id.btn_begin_date); btnEndDate = (Button) findViewById(R.id.btn_end_date); btnBeginDate.setOnClickListener(this); btnEndDate.setOnClickListener(this); findViewById(R.id.btn_add).setOnClickListener(this); findViewById(R.id.btn_reset).setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_reset: reset(); break; case R.id.btn_add: add(); break; case R.id.btn_begin_date: typeDate = BEGIN_DATE; showDatePicker(); break; case R.id.btn_end_date: typeDate = END_DATE; showDatePicker(); break; default: break; } } private void showDatePicker() { Calendar now = Calendar.getInstance(); DatePickerDialog dpd = DatePickerDialog.newInstance( this, now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH) ); String title; if (typeDate == BEGIN_DATE) { title = context.getResources().getString(R.string.begin_date); } else { title = context.getResources().getString(R.string.end_date); } dpd.show(getFragmentManager(), title); } @Override public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { String date = dayOfMonth + "/" + monthOfYear + "/" + year; if (typeDate == BEGIN_DATE) { beginDate = date; btnBeginDate.setText(date); } else { endDate = date; btnEndDate.setText(date); } } private void reset() { editName.setText(""); editPhone.setText(""); editName.requestFocus(); } private void add() { String name = editName.getText().toString().trim(); String phone = editPhone.getText().toString().trim(); // not enter nick name if (name.length() == 0) { editName.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_nick)); return; } // not enter pass if (phone.length() == 0) { editPhone.requestFocus(); Var.showToast(context, context.getResources().getString(R.string.enter_pass)); return; } HashMap<String, String> map = new HashMap<>(); map.put(Var.KEY_NICK, nick); map.put(Var.KEY_NAME, name); map.put(Var.KEY_PHONE, phone); map.put(Var.KEY_BEGIN_DATE, beginDate); map.put(Var.KEY_END_DATE, endDate); loadJson.sendDataToServer(Var.METHOD_ADD_OLD_LOVER, map); progressDialog.show(); } @Override public void finishLoadJSon(String error, String json) { if (progressDialog.isShowing()) { progressDialog.hide(); } try { if (json != null) { JSONObject jsonObject = new JSONObject(json); if (jsonObject.getBoolean(Var.KEY_ADD)) { Var.showToast(context, context.getResources().getString(R.string.add_success)); finish(); } else { Var.showToast(context, context.getResources().getString(R.string.add_fail)); } } else { Var.showToast(context, error); } } catch (JSONException e) { e.printStackTrace(); } } }
Activity Main – List Lover
Trong này có 2 phần chúng ta cần xử lý là list và Adapter cho list.
File MainActivity.java
package cachhoc.net.demojson; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; import java.util.ArrayList; import java.util.HashMap; public class MainActivity extends AppCompatActivity implements View.OnClickListener, LoadJson.OnFinishLoadJSonListener { private ItemAdapter adapter; private ArrayList<Lover> list; private LoadJson loadJson; private Context context; private ProgressBar progressBar; private ViewGroup layoutProgress; private TextView tvNotify; private String nick; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; loadJson = new LoadJson(); loadJson.setOnFinishLoadJSonListener(this); setupToolbar(); setupRecyclerView(); findViewById(R.id.fab_add).setOnClickListener(this); layoutProgress = (ViewGroup) findViewById(R.id.layout_progress); progressBar = (ProgressBar) findViewById(R.id.progress); tvNotify = (TextView) findViewById(R.id.tv_notify); nick = getIntent().getStringExtra(Var.KEY_NICK); } private void setupToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); if (toolbar != null) { setSupportActionBar(toolbar); } } private void setupRecyclerView() { RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_lover); // If the size of views will not change as the data changes. recyclerView.setHasFixedSize(true); // Setting the LayoutManager. RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); // Setting the adapter. list = new ArrayList<>(); adapter = new ItemAdapter(context, list); recyclerView.setAdapter(adapter); } public void onResume() { super.onResume(); refresh(); } /** * re load data from server */ private void refresh() { HashMap<String, String> map = new HashMap<>(); map.put(Var.KEY_NICK, nick); loadJson.sendDataToServer(Var.METHOD_GET_OLD_LOVER, map); layoutProgress.setVisibility(View.VISIBLE); progressBar.setVisibility(View.VISIBLE); tvNotify.setVisibility(View.GONE); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_logout: logout(); break; case R.id.action_refresh: refresh(); break; } return super.onOptionsItemSelected(item); } private void logout() { Intent intent = new Intent(context, LoginActivity.class); startActivity(intent); finish(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.fab_add: addOldLover(); break; } } private void addOldLover() { Intent intent = new Intent(context, AddLoverActivity.class); intent.putExtra(Var.KEY_NICK, nick); startActivity(intent); } @Override public void finishLoadJSon(String error, String json) { if (json != null) { layoutProgress.setVisibility(View.GONE); updateList(json); } else { showNotify(error); } } private void updateList(String json) { ArrayList<Lover> newList = LoadJson.jsonToListLover(json); list.clear(); list.addAll(newList); adapter.notifyDataSetChanged(); if (list.size() == 0) { showNotify(context.getResources().getString(R.string.no_lover)); } } private void showNotify(String notify) { layoutProgress.setVisibility(View.VISIBLE); progressBar.setVisibility(View.GONE); tvNotify.setVisibility(View.VISIBLE); tvNotify.setText(notify); } /** * double click back then exit app (2 click in 2s to exit) */ @Override public void onBackPressed() { if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Var.showToast(context, context.getResources().getString(R.string.back_to_exit)); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce = false; } }, 2000); } private boolean doubleBackToExitPressedOnce; }
Trong này các bạn chú ý là ở cuối mình viết đè phương thức onBackPressed để thông báo người dùng ấn back 2 lần trước khi thoát. 2 lần ấn này phải liên tiếp trong vòng 2s (200 mili giây)
File ItemAdapter.java
package cachhoc.net.demojson; import android.content.Context; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; import java.util.List; public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.RecyclerViewHolder> { private List<Lover> list; private Context context; public ItemAdapter(Context context, List<Lover> list) { this.context = context; this.list = list; } @Override public int getItemCount() { return list.size(); } /** * connect to item view */ @Override public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) { LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); View itemView = inflater.inflate(R.layout.item, viewGroup, false); return new RecyclerViewHolder(itemView); } /** * set data for item */ @Override public void onBindViewHolder(RecyclerViewHolder viewHolder, int position) { Lover lover = list.get(position); viewHolder.tvName.setText(lover.getName()); viewHolder.tvPhone.setText(lover.getPhone()); viewHolder.tvBeginDate.setText(lover.getBeginDate()); viewHolder.tvEndDate.setText(lover.getEndDate()); } /** * ViewHolder for item view of list */ public class RecyclerViewHolder extends RecyclerView.ViewHolder implements OnClickListener { public CardView container; public TextView tvName; public TextView tvPhone; public TextView tvBeginDate; public TextView tvEndDate; public RecyclerViewHolder(View itemView) { super(itemView); container = (CardView) itemView.findViewById(R.id.item_container); tvName = (TextView) itemView.findViewById(R.id.tv_name); tvPhone = (TextView) itemView.findViewById(R.id.tv_phone); tvBeginDate = (TextView) itemView.findViewById(R.id.tv_begin_date); tvEndDate = (TextView) itemView.findViewById(R.id.tv_end_date); container.setOnClickListener(this); } // click item then display note @Override public void onClick(View v) { Var.showToast(context, list.get(getAdapterPosition()).getName()); } } }
Vậy là chúng ta đã hoàn thiện ứng dụng. Bài tuy hơi dài nhưng không khó.
Các bạn có thể download project tại đây
Download File Chạy OldLover.apk
Chúc các bạn học tập vui vẻ 🙂
Bài viết được thực hiện trong loạt bài hướng dẫn JSon trong Android bởi nguyenvanquan7826
anh cho em hỏi https://cachhoc.net/mobile/demo-json/lover.php này em đọc bài của anh mà ko hiểu là lấy từ đâu
Mình xuất từ database của mình, bạn xem bài hướng dẫn số 2 nhé
https://www.cachhoc.net/2015/08/18/android-json-trong-android-phan-2-xuat-json-tu-database-bang-php/
Cho mình hỏi 1 chút được không. Mình tạo database sau đó đẩy dữ liệu vào trong database . Dữ liệu mình đưa vào là công thức toán học nên khi vào trong database nó không hiển thị được dẫn đến việc trả ra chuổi JSON cũng không hiển thị được công thức toán học. Bạn cho hình hỏi có cách nào xử lý không? Mình cảm ơn
Ah, Về công thức toán học mình cũng chưa thử qua, chưa rõ nó như thế nào
Cho mình hỏi có thể hiển thị các thẻ html trên listview như trên html k vậy?
Cho hỏi, không biết mình làm đúng không mà dữ liệu viết bằng tiếng Việt khi gửi đi không thể lưu vào được database trên web, kết quả là = khoảng trắng, bạn có cách nào sửa được lỗi này không, và như JSON của bạn L\u00f2 L\u1ea5p L\u00f3, đọc từ Android có thể decode nó lại đúng như ban đầu không vậy. Cám ơn.
Bạn xem thử lại định dạng chữ trên database xem, mình hay để là utf-8 unicode
Mình đã sửa được rồi, cảm ơn bạn nhiều, bài viết rất hữu ích. Cho mình hỏi thêm là nếu muốn gửi đi nhiều Array List, thay vì phải gửi một lần, làm thế nào để chỉ gửi trong 1 lần không.
Bạn cứ cho vào 1 object nào đó chứa nhiều List là được
Bạn ơi mình cũng giống như bạn không biết xử lý sao giúp mình được không bạn
Bạn xem lại đinh dạng font chữ trên database xem nhé. thường là utf8
Anh ơi, cho em hỏi: em có Link api_url, dừng phương thức post để gửi dữ liệu lên cái url đó thôi thì có thể bỏ qua class Var.java và Lover.java đúng không ạ? và class LoadJson.java nên thay đổi thế nào ạ?
class Var chỉ để lưu các hằng url thôi, bạn bỏ đi cũng được, thay vào đó bạn truyền url trực tiếp.