Wednesday, October 4, 2017

Xóa mất hẳn dòng Listview.

Sau khi đã biết cách ghi và đọc dữ liệu, bây giờ ta sẽ xóa dòng ListView mà sau đó mở lại class thì nó đã mất dòng đó chứ không hiện lại toàn bộ như trước.
Để làm việc này, ta nhớ lại đã thực hành xóa dòng Listview trong class forth, hoặc class của bạn thì bạn sẽ lại làm ở đó.
Ta sẽ biến mảng qua thành một file có tên danhsach.txt mà từng dòng của nó là từng phần tử của mảng.
Mục đích là để sang bên class forth có xóa dòng, ta sẽ dùng file này để xóa, khi xóa thì ta lưu file mới để mỗi khi bật ra class forth nó không load lại toàn bộ mảng nếu ta cứ dùng cái mảng quả cố định.
Và chú ý là tại class MainActivity này ta chỉ ghi file danhsach.txt duy nhất một lần đầu tiên. Nếu lần nào mở ra cũng ghi, ta sẽ lại có liên tiếp các phần tử quả nối đuôi vào danh sách.
Để làm việc này, trước khi ghi ta sẽ đọc file danhsach.txt ra thành mảng, nếu mảng rỗng tức là chưa có file đó thì ta mới ghi. Còn nếu đã có dữ liệu thì ta không ghi nữa.
Bắt đầu làm.
Hãy khai báo một ArrayList có tên kiemtra.
ArrayList<String> kiemtra = new ArrayList<String>();
Sau đó đọc file danhsach.txt.
String line = "";
          try {
FileInputStream In = openFileInput("danhsach.txt");
InputStreamReader inputReader = new InputStreamReader(In);
BufferedReader BR = new BufferedReader(inputReader);
          while ((line = BR.readLine()) != null) {
          kiemtra.add(line);
          }
          BR.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
Tiếp theo kiểm tra độ dài của mảng xem, nếu =0 tức chưa có file danhsach, ta mới ghi dữ liệu vào.
if(sophantu==0){
         try {
FileOutputStream fos = openFileOutput(
                        "danhsach.txt", Context.MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(
                        fos);
          for (int i = 0; i < qua.length; i++) {
          osw.append(qua[i] + "\n");
              }
              osw.flush();
              osw.close();
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          }
Nhập các thư viện cần dùng vào. Sửa lệnh ở nút b2 để nó mở sang đúng class có ListView sẽ xóa dòng, tức class forth.


Tại class forth, khai báo mảng qua2 để đọc các phần tử trong file danhsach.txt vào nó. Nếu trước đó bạn đã thực hành add các phần tử quả vào nó rồi thì giờ bỏ hết đi, rào thành comment, đảm bảo qua2 là rỗng.
Lệnh đọc file danhsach.txt ra mảng như sau:
String line = "";
try {
FileInputStream In = openFileInput("danhsach.txt");
InputStreamReader inputReader = new InputStreamReader(In);
BufferedReader BR = new BufferedReader(inputReader);
          while ((line = BR.readLine()) != null) {
          qua2.add(line);
          }
          BR.close();
          } catch (IOException e) {
          e.printStackTrace();
          }   
Ta tạo một file xml có tên li3 trong thư mục layout, trong đó có một checked textView.
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="fill_parent"
    android:layout_height="46dp"
    android:checkMark="@android:drawable/btn_radio"
    android:gravity="center_vertical"
    android:paddingLeft="2dip"
    android:paddingRight="2dip"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#000080"
    android:textSize="17sp" />

Mục đích để ListView có nút chọn nhìn bắt mắt hơn, sau đó set adapter.
adapter=new ArrayAdapter<String>(this,R.layout.li3,R.id.text, qua2);
Trong nút xóa, ta kiểm tra xem đã chọn dòng chưa, nếu chọn rồi ta xóa dòng, bỏ phần tử cần xóa trong mảng đi, xóa file danhsach, đồng thời lấy mảng đã bỏ phần tử ghi lại thành file cũng có tên là danhsach.txt. Kèm theo đó là thông báo đã xóa dòng ra màn hình.
Toàn bộ code nút xóa bây giờ như sau.
b1.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
     if (dem == 0) {
Toast.makeText(forth.this, "Bạn chưa chọn dòng",
                                  Toast.LENGTH_SHORT).show();
} else {
SparseBooleanArray checked = lv.getCheckedItemPositions();
          for (int i = 0; i < lv.getCount(); i++) {
              if (checked.get(i) == true) {
                   qua2.remove(i);
                   }
              adapter.notifyDataSetChanged();
          }
          lv.clearChoices();
          deleteFile("danhsach.txt");
     try {
FileOutputStream fos = openFileOutput("danhsach.txt",
                                      Context.MODE_APPEND);
OutputStreamWriter osw = new OutputStreamWriter(fos);
     for (int i = 0; i < qua2.size(); i++) {
          osw.append(qua2.get(i) + "\n");
          }
          osw.flush();
          osw.close();
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
          e.printStackTrace();
     } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     }
     dem = 0;
Toast.makeText(forth.this, "Dữ liệu đã được xóa",
                                  Toast.LENGTH_SHORT).show();
     }
}
});
Chạy thử, xóa dòng rồi mở lại, dòng bị xóa đã không còn hiện lại nữa.
Bài này chính là cách ứng dụng bài xóa dòng đơn giản trước đây. Trong thực tế ta sẽ làm tương tự thế này chứ không phải xóa rồi mở lại vẫn như cũ.
Sự thực hành này giúp bạn quen với cái gọi là tư duy lập trình, tức cách xử lý các tình huống phát sinh trong thực tế, như ở đây là làm sao để mở lại class thì không có dữ liệu bị ghi lại lần nữa.
Thử xóa toàn bộ các phần tử, thoát ứng dụng, mở lại, bạn sẽ thấy mảng lại đầy đủ như bau đầu.
Đó là vì khi đã xóa hết thì bật ứng dụng lên, file danhsach.txt không có dòng nào thì mảng cũng trắng. Do đó lệnh ghi ở class mở đầu lại ghi vào đầy đủ các dòng.
Do đây là ví dụ, ta không cần quan tâm.
Nhưng nếu buộc để xóa trắng thì mở lại không còn gì nữa, ta sẽ có cách làm thêm một chút.
Kiểu như ở class forth, trước khi thoát về ta kiểm tra số phần tử mảng, nếu bằng 0 là ta biết đã xóa trắng, ta sẽ chuyển ngược về class MainActivity một biến đếm. Mỗi lần mở ứng dụng lại kiểm tra biến đếm, nếu nó bằng số 1 tức đã xóa trắng thì ta không ghi lại nữa.

Đó là cách ta xử lý yêu cầu phát sinh. 



No comments:

Post a Comment