Thursday, February 24, 2011

Tạo image header (hay title bằng image) của ứng dụng trên android

Bài trước tôi đã giới thiệu cách control một layout với Image và title. Lần này thêm một bài nữa về layout nhé :D.
Vì vấn đề thương hiệu, các sếp đã bắt Tên của ứng dụng nên để logo của ứng dụng chứ ko chỉ là để chữ không. Mặc định thì nó chỉ hiển thị tên ứng dụng bạn khai báo trong file Manifest. Nhưng bạn hoàn toàn có thể control nó theo ý của mình.

Trước hết tôi design layout main_header cho Title đó như sau.


 

  
 

Ở đây tôi chỉ đưa một image vào đó, nhưng bạn hoàn toàn có thể cho những thứ mà bạn thích vào đây.

Có layout rồi, nhưng làm thế nào để load được nó đây. Bạn để ý thấy trong thẻ Application của file Manifest có thuộc tính sau android:label="@string/app_name":



Cái này chính là cái hiển thị title của ứng dụng.
Ta sẽ ghi đè lên title như sau.
Tạo một style TitleCustomTheme như sau:


 
  
  
 

Và thêm thuộc tính android:theme="@style/TitleCustomTheme" vào trong thẻ application như sau.



Trong class Activity ta load layout đã design như sau:

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.main_header);

Xem thử kết quả nhé. Nhắc bạn luôn nhớ rằng, thương hiệu luôn là vấn đề sống còn của doanh nghiệp :D.

Xem ảnh demo:

Tuesday, February 22, 2011

Xây dựng grid layout cho android với mỗi phần tử bao gồm Icon + title.

Do dạo này bận dự án quá nên chưa viết loạt bài lập trình game 3D tiếp được, loạt bài này tôi sẽ chỉ các bạn một số thủ thuật trong khi tôi làm dự án của mình.
Giới thiệu sơ qua về dự án của tôi, nó được xây dựng cho mảng bán content cho người dùng giống như Sóc Bay hay một số các phần mềm khác.
Hôm nay tôi sẽ chỉ cách cho các bạn thiết kế layout cho màn hình chính của chương trình. Đó là Grid Layout mỗi phần tử bao gồm các Icon + title bên dưới.
Trước hết chúng ta phải xây dựng được layout cho phần tử bên trong, cái này thì đơn giản quá nhỉ, chỉ cần một ImageView và một TextView là được. Nó trông giống như:

 
  
  
  
  
 

Trong main Activity bạn load View như sau
GridView gridview = (GridView) findViewById(R.id.gridview);
 gridview.setAdapter(new ImageAdapter(this, dictionary, dictionary.getChildList().size()));

Trong đó class ImageAdapter load các phần tử ta xây dựng bên trên và xây dựng lớp đó như sau

package vn.vdco.mzone;

import vn.vdco.mzone.util.DictionaryNode;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * 
 * @author TanNM
 *
 */
public class ImageAdapter extends BaseAdapter {
 private Context mContext;
 private DictionaryNode dictionary;
 private int sizeArray;
 private Integer[] mThumbIds = null;
 private String[] mTitle = null;

 /**
  * 
  * @param c
  * @param dictionary
  * @param sizeArray
  */
 public ImageAdapter(Context c, DictionaryNode dictionary, int sizeArray) {
  this.mContext = c;
  this.dictionary = dictionary;
  this.sizeArray = sizeArray;
  mTitle = new String[sizeArray];
  mThumbIds = new Integer[sizeArray];
 }

 public int getCount() {
  return mThumbIds.length;
 }

 public Object getItem(int position) {
  return null;
 }

 public long getItemId(int position) {
  return 0;
 }

 /**
  * Load layout for Item with Icon and title
  * @param position
  * @param convertView
  * @param parent
  * @return View
  * @author tannm
  */
 public View getView(int position, View convertView, ViewGroup parent) {
  ImageView iv;
  TextView tv;
  View v;
  init();
  if (convertView == null) {
   LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   v = li.inflate(R.layout.main_icon, null);
   tv = (TextView)v.findViewById(R.id.icon_text);
   tv.setText(mTitle[position]);
   iv = (ImageView)v.findViewById(R.id.icon_image);
   iv.setImageResource(mThumbIds[position]);
  } else {
   v = convertView;
  }

  return v;
 }

 /**
  * Load title and icon in config file to array
  * @author tannm
  */
 private void init()
 {
  if(dictionary != null && dictionary.getChildList() != null && dictionary.getChildList().size() >0)
  {
   for (int i = 0; i < sizeArray; i++) {
    DictionaryNode node = (DictionaryNode)dictionary.getChildList().get(i);
    int resID = this.mContext.getResources().getIdentifier("vn.vdco.mzone:drawable/" + node.getString("$Image$"), null, null);
    mThumbIds[i] = resID;
    mTitle[i] = node.mstrValue;
   }
  }
 }
}

Ở trên tôi có dùng một đối tượng DictionaryNode để lưu trữ cấu hình các image và title cho các phần tử. Bạn có thể xem cách load nó trong phương thức init().
Cấu trúc của nó kiểu như sau:
MainMenu
     NEWS==Đọc báo
          $Image$==n
     FUNNY==Hài hước
          $Image$==hh
....
Khi đó ta sẽ load động các hình ảnh và title từ file cấu hình vào. Chú ý, nếu cái này ko cần thiết bạn nên Fix vì trong điện thoại cần tiết kiệm dung lượng và các sử lý không cần thiết tới mức tối đa do bộ nhớ và CPU nhỏ.

Chúc bạn có một layout tuyệt vời cho ứng dụng của bạn.