Giới thiệu về phát triển Android khi sử dụng Eclipse và các widget của Android(P4)

Giới thiệu về phát triển Android khi sử dụng Eclipse và các widget của Android(P4)

Sử dụng widget : Một ứng dụng mẫu

Trong phần này, chúng ta sẽ tạo một ứng dụng mẫu (xem hình 9a, 9b) để hiển thị tất cả các địa chỉ liên lạc trong danh bạ điện thoại bằng cách sử dụng widget listView. Mục đích của ví dụ này là để giới thiệu không chỉ là việc sử dụng widget listView mà còn cho thấy dữ liệu điện thoại có thể được tìm nạp như thế nào khi sử dụng các lớp ContentProvider và ContentResolver. Hãy chú ý đến các tệp XML của giao diện người dùng vì có hai cách bố trí giao diện người dùng: một để xác định cách widget listView sẽ hiển thị danh sách khít với giao với giao diện người dùng chính và cái kia để xác định cách hiển thị từng phần tử của danh sách đó. Một điểm quan trọng là thiết lập các quyền hạn cho các ứng dụng có thể đọc dữ liệu điện thoại. Ví dụ này là bước đầu tiên để hiểu được cách có thể kết hợp các ý định (intent) và các bộ lọc ý định trong một ứng dụng. Mặc dù các intent nằm ngoài phạm vi của bài viết này, nhưng độc giả cũng nên lưu ý rằng để chuyển ứng dụng của ví dụ này thành một ứng dụng danh bạ điện thoại trong thế giới thực, chỉ cần triển khai thực hiện các thao tác nhấn vào các mục của danh sách và tạo một ý định (intent) cuộc gọi và bộ lọc ý định để bắt đầu một cuộc gọi đến địa chỉ liên lạc được chọn.

Trong ví dụ này, các địa chỉ liên lạc sẽ được hiển thị theo mẫu thẳng theo chiều dọc và địa chỉ liên lạc được chọn sẽ xuất hiện ở đầu danh sách với một phông chữ in nghiêng lớn và một nền màu xanh dương. Chúng ta cũng có một hộp kiểm tra ở phía dưới cùng bên trái của màn hình, mà khi được đánh dấu chọn, sẽ hiển thị chỉ các địa chỉ liên lạc được đánh dấu sao (hoặc các địa chỉ liên lạc ưa thích). Tiêu đề của ứng dụng trong trường hợp này là "Contact Manager (Trình quản lý các địa chỉ liên lạc). Ở đây chúng ta sử dụng ba loại widget: textView, listViewcheckBox. Chúng ta sử dụng widget textView để hiển thị địa chỉ liên lạc hiện đang được chọn. Bạn có thể đoán ngay rằng widget listView là một danh sách các widget textView. Widget listView sử dụng các mẫu thiết kế của bộ tiếp hợp để kết nối dữ liệu (trong trường hợp này là các địa chỉ liên lạc) và một khung nhìn dữ liệu (trong trường hợp này là một textView cho listView này. Mọi thao tác nhấn trên listView có thể được bắt giữ lại bằng cách thực hiện phương thức AdapterView.OnItemClickListener().

Trước khi tiếp tục, chúng ta nên có một số các địa chỉ liên lạc được lưu trong phần các địa chỉ liên lạc của trình mô phỏng thiết bị của Android (AVD). Điều này có thể được thực hiện bằng cách nhấn vào Contacts (Các địa chỉ liên lạc) trên màn hình chủ của AVD, sau đó nhấn vào Menu để có tùy chọn Add Contacts (Thêm các địa chỉ liên lạc). Phần Favorites (Các địa chỉ liên lạc ưa thích) cho biết cách đánh dấu một địa chỉ liên lạc như là ưa thích/được đánh dấu sao.

Hình 9a. Ứng dụng các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc trong một widget listView

Hình 9b. Ứng dụng các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc được đánh dấu sao trong một widget listView khi đánh dấu chọn vào hộp kiểm tra hiển thị các địa chỉ liên lạc có đánh dấu sao

Bây giờ chúng ta sẽ định nghĩa một vài chuỗi.

Liệt kê 5. Các chuỗi được định nghĩa trong tệp strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="hello">Hello World, Manager!</string> 
  <string name="app_name">Contact Manager</string> 
  <string name="selectedEntry" /> 
  <color name="White">#FFFFFF</color> 
  <color name="Black">#000000</color> 
  <color name="Blue">#0000FF</color> 
 <string name="showStarred">Show starred contacts only</string>
</resources>

Tệp main.xml

Chúng ta hãy định nghĩa cách bố trí chính cho ứng dụng của mình. Widget listView sẽ cung cấp danh sách tất cả các địa chỉ liên lạc trong danh bạ điện thoại. listView hiển thị từng mục bên trong một widget textView, mà chúng ta sẽ định nghĩa tiếp sau.

Liệt kê 6. Tệp main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/
apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:id="@+id/selectedContact" 
    android:padding="10dp" 
    android:textSize="20sp" 
    android:textStyle="italic" 
    android:typeface="serif" 
    android:background="@color/Blue" 
    android:textColor="@color/White" 
    android:text="@string/selectedEntry"/>
<ListView 
    android:id="@+id/contactsListView" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_weight="1">
    </ListView>
<CheckBox android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/showStarred"
    android:text="@string/showStarred"/>
</LinearLayout>

Lưu ý rằng việc gán cho thuộc tính layout_weight giá trị bằng 1 trong listView bảo đảm chắc chắn rằng danh sách phủ hết vùng màn hình càng lớn càng tốt cho đến khi một widget mới được định nghĩa.

Tệp contactItem.xml

Bên cạnh bố trí chính, chúng ta cần phải xác định một cách bố trí khác ở đây. Việc này là để thể hiện từng phần tử trong listView này. Ở đây, ta sử dụng một textView đơn giản.

 Liệt kê 7. Mã cho widget textView, thiết lập từng phần tử của widget listView

<?xml version="1.0" encoding="utf-8"?>
<TextView
  xmlns:android="http://schemas.android.com/
apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:padding="5dp" 
  android:textStyle="bold" 
  android:id="@+id/contactItem">
</TextView>

Lưu ý rằng theo mặc định Android cung cấp một cách bố trí đơn giản, có thể được sử dụng thay cho định nghĩa riêng của bạn. Điều này có thể được tham chiếu qua android.R.layout.simple_list_item_1.

Tệp ManageContacts.java

Liệt kê 8 cho thấy hoạt động chính được triển khai thực hiện như thế nào. Phương thức populateContactList() là một phương thức mà chúng ta sử dụng để truy vấn cơ sở dữ liệu các địa chỉ liên lạc và hiển thị chúng trong listView này.

Liệt kê 8. Triển khai thực hiện của hoạt động chính

public class ManageContacts extends Activity {
    private ListView mContactList;
    private CheckBox mCheckBox;
    private boolean mShowStarred;
    private TextView selectedText;
     /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mContactList = (ListView) findViewById(R.id.contactsListView);
        mCheckBox = (CheckBox) findViewById(R.id.showStarred);
        selectedText = (TextView) findViewById(R.id.selectedContact);
        mShowStarred = false;
        
        mCheckBox.setOnCheckedChangeListener(new CheckChangedListener());
        
        mContactList.setOnItemClickListener(new ClickListener());
        
        populateContactList();
       
    }
    
    public void populateContactList() {
         Uri uri = ContactsContract.Contacts.CONTENT_URI;
         String[] projection = new String[] {
                 ContactsContract.Contacts._ID,
                 ContactsContract.Contacts.DISPLAY_NAME,
         };
         String[] selectionArgs = null;
         String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + 
" COLLATE LOCALIZED ASC";
         String selection = mShowStarred? 
ContactsContract.Contacts.STARRED + 
" ='1'" : null;
         Cursor c = getContentResolver().query(uri,
 projection, selection, selectionArgs, 
sortOrder);
         
         String[] fields = new String[] {
                 ContactsContract.Data.DISPLAY_NAME
         };
         SimpleCursorAdapter adapter = new 
SimpleCursorAdapter(this, R.layout.contactitem,
c, fields, new int[] {R.id.contactItem});
         mContactList.setAdapter(adapter);
         
    }
    
    private class ClickListener implements OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> arg0,
 View textView, int pos, long arg3) {
            if(textView instanceof TextView)
                selectedText.setText(((TextView) textView).getText());
         }
     }
    
    private class CheckChangedListener implements 
OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(CompoundButton 
buttonView, boolean isChecked) {
             mShowStarred = isChecked;
             selectedText.setText("");
             populateContactList();
            
        }
        
    }
}

Những điều cần lưu ý:

  • Chúng ta có hai trình lắng nghe — một trình lắng nghe để xử lý các lần nhấn vào một mục của danh sách và cái kia để xử lý các lần nhấn vào hộp kiểm tra. Trình lắng nghe đầu tiên chỉ đơn giản đặt văn bản trong hộp textView màu xanh dương với tên hiển thị của địa chỉ liên lạc hiện đang được chọn. Trình lắng nghe sau là để thiết lập trường mShowStarred và điền lại danh sách.
  • Để đọc các địa chỉ liên lạc từ cơ sở dữ liệu điện thoại, chúng ta cần phải truy vấn nó để có được một con trỏ. Truy vấn này có các tham số sau:
    1. uri — URI sử dụng content:// scheme để lấy ra nội dung.
    2. projection (hình chiếu) — Một danh sách các cột nào sẽ được trả về. Nếu cho bằng null sẽ trả về tất cả các cột; điều này không nên làm để tránh đọc nhiều dữ liệu từ bộ nhớ mà sẽ không dùng hết.
    3. selection (lựa chọn) — Một bộ lọc khai báo sẽ trả về hàng nào, được định dạng như là một mệnh đề WHERE của SQL (ngoại trừ chính từ khóa WHERE). Cho bằng null sẽ trả về tất cả các hàng có trong URI đã cho.
    4. selectionArgs — Bạn có thể bao gồm các dấu hỏi ?, chúng sẽ được thay thế bằng các giá trị từ selectionArgs, theo đúng trình tự mà chúng xuất hiện trong selection. Các giá trị này sẽ bị buộc như là kiểu chuỗi ký tự (String).
    5. sortOrder — sắp xếp các hàng như thế nào, được định dạng như là một mệnh đề SQL ORDER BY của SQL (ngoài trừ chính từ khóa ORDER BY). Cho bằng null sẽ sử dụng thứ tự sắp xếp mặc định, mà theo mặc định có thể là không theo thứ tự nào cả.

Con trỏ của tập hợp kết quả đã thu được phải được liên kết với giao diện người dùng qua một bộ tiếp hợp (adapter). Chúng ta sử dụng một SimpleCursorAdapter ở đây, mặc dù Android cũng cung cấp một ListAdapter. Khi nhận được bộ tiếp hợp chúng ta cần phải gắn nó kèm theo vào listView và thế là xong.

Các quyền hạn

Một bước cuối cùng trước khi ứng dụng của chúng ta sẽ chạy thành công trên một thiết bị Android là thiết lập các quyền hạn. Không có các quyền hạn để có thể đọc cơ sở dữ liệu các địa chỉ liên lạc, nhân (kernel) Linux trong thiết bị đó sẽ không cho phép các ứng dụng làm như vậy. Vì vậy, hãy vào AndroidManifest.xml>Permissions tab và thiết lập các quyền hạn sau:

  1. android.permission.GET_ACCOUNTS
  2. android.permission.READ_CONTACTS

Các quyền hạn này có thể được thiết lập bằng cách nhấn vào biểu tượng U và định nghĩa quyền hạn. Hình 10 cho thấy tab permissions trông như thế nào.

Hình 10. Bản kê các quyền hạn của Android

Widget listView khi sử dụng ListActivity

Ví dụ này được dùng để trình bày một cách khác để triển khai thực hiện một listView. Trong ứng dụng trên, lưu ý rằng hoạt động chính của chúng ta triển khai thực hiện lớp hoạt động. Khi đề cập đến các widget listView, đôi khi lớp ListActivity tỏ ra rất tiện lợi vì nó có các API công cộng để xử lý các lần nhấn vào các mục danh sách, thiết lập các bộ tiếp hợp của danh sách, lấy vị trí nơi nhấn vào, v.v.

Chúng ta có thể sửa đổi (mã lệnh của) hoạt động của mình để triển khai thực hiện lớp ListActivity như trong Liệt kê 9.

Liệt kê 9. Triển khai thực hiện bằng cách sử dụng lớp ListActivity

public class ManageContacts extends ListActivity {
    @Override
    protected void onListItemClick(ListView l, View v, 
int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
if(v instanceof TextView)
selectedText.setText(((TextView) v).getText());
}
private CheckBox mCheckBox;
private boolean mShowStarred;
private TextView selectedText;
/** Called when the activity is first created. */
@Override
public void 
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mCheckBox = (CheckBox) findViewById(R.id.showStarred);
selectedText = (TextView) 
findViewById(R.id.selectedContact);
mShowStarred = false;

mCheckBox.setOnCheckedChangeListener(new 
CheckChangedListener());

populateContactList();

}

public void populateContactList() {
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
};
String[] selectionArgs = null;
String sortOrder = 
ContactsContract.Contacts.DISPLAY_NAME +      
" COLLATE LOCALIZED ASC";
String selection = mShowStarred?
ContactsContract.Contacts.STARRED + " ='1'" : null;
Cursor c = 
getContentResolver().query(uri, projection, 
selection, selectionArgs, sortOrder);

String[] fields = new String[] {
ContactsContract.Data.DISPLAY_NAME
};
ListAdapter adapter = new 
SimpleCursorAdapter(this, 
R.layout.contactitem, c, fields, new 
int[]{R.id.contactItem});
setListAdapter(adapter);

}

private class CheckChangedListener 
implements OnCheckedChangeListener {

@Override
public void onCheckedChanged(CompoundButton 
buttonView, boolean isChecked) {
mShowStarred = isChecked;
selectedText.setText("");
populateContactList();
   }
        
    }
}

Lưu ý rằng ở đây chúng ta chỉ cần triển khai thực hiện phương thức onListItemClick của lớp ListActivity, thay vì khai báo một lớp ẩn danh để xử lý các lần nhấn. Ở đây, chúng ta cũng không cần phải tham chiếu đến widget listView được xác định trong tệp main.xml vì lớp ListActivity giả định rằng widget listView được định nghĩa với mã định danh là @android:id/list. Đây là lưu ý quan trọng. Bất cứ khi nào chúng ta sử dụng lớp ListActivity, chúng ta phải định nghĩa widget listView trong tệp main.xml để có một mã định danh @android:id/list; nếu không, lớp ListActivity sẽ không biết tham chiếu đến listView nào.

 

Bạn thấy bài viết này như thế nào?: 
Average: 10 (1 vote)
Ảnh của Binh Tran Thanh

Drupal Consultant

Started my career as a drupal8 developer in EM Solutions . I love learning Web technologies like HTML, CSS, PHP, Jquery Ajax and Drupal backend . Currently working as a drupal backend developer.

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Tính năng mới: Toolbar, Inline Editing, Languages trong Drupal 8

Tính năng mới: Toolbar, Inline Editing, Languages trong Drupal 8

Over the last few months, we've been covering the Drupal community's progress towards releasing Drupal 8.

Communicate for FREE through Nimbuzz Android App

Communicate for FREE through Nimbuzz Android App

The Android Market is full of multinetworking instant messaging clients and Nimbuzz is one of them.

Drupal Extension với Behat and Mink cung cấp system để test

Drupal Extension với Behat and Mink cung cấp system để test

To test any Drupal site, at some point you'll need to set up test data. You can do this in a blackbox fashion, using pre-built steps to create a user – and log in via the interface

Công ty diệt chuột T&C

 

Diet con trung