2013年9月30日月曜日

リストビューの基礎(ListView, BaseAdapter)


これもまた、よくあるUIの
リストビューの作り方を説明します。

基本的な作り方はGridViewと同じで、

ListViewオブジェクトの生成
adapterの生成
adapterにアイテムを入れる
ListViewにadapterをsetな流れです。


サンプルソースでは
アイコン(画像)と共に文字をクラスに格納させ、画面に表示させています。

行の中にレイアウトを作成しているので、
固定的なリストビューでなく、カスタマイズ可能なリストビューになっています。

package com.example.pururun;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnItemClickListener{

    private List dataList = new ArrayList();
 
    private final int MP = ViewGroup.LayoutParams.MATCH_PARENT;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        //基礎のレイアウトを作成
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
        //今回の主役リストビューの生成
        ListView oListView   = new ListView(getApplicationContext());
        //リストビューに入れるアイテムのAdapterを生成
        ListAdapter     oAdp = new ListAdapter(getApplicationContext());

        //リストビューのレイアウトを指定
        oListView.setLayoutParams(new LinearLayout.LayoutParams(MP, MP));
        //リストビューにアイテムadapterを設定
        oListView.setAdapter(oAdp);
        //リストビューをクリックした時の処理を設定
        oListView.setOnItemClickListener(this);

        for (int i = 0; i < 10; i ++){
            //配列にタイトルと画像を格納
            dataList.add(new ListItem(String.valueOf("番号:" + i), R.drawable.ic_launcher));
        }
        
        //Adapteの中身を更新
        oAdp.notifyDataSetChanged();

        //基礎のレイアウトにリストビューを追加
        oLayout.addView(oListView);
        //基礎のレイアウトを画面に設定
        setContentView(oLayout);
    }
 
    public class ListAdapter extends BaseAdapter{

        private Context mContext;
  
        public ListAdapter(Context context){
            //生成時のコンストラクターでコンテクストを取得
            mContext = context;
        }
  
        @Override
        public int getCount() {
            //リストの行数
            return dataList.size();
        }

        @Override
        public Object getItem(int posion) {
            //配列の中身を返す
            return dataList.get(posion);
        }

        @Override
        public long getItemId(int posion) {
            //現在の配列の場所
            return posion;
        }

        @Override
        public View getView(int position, View view, ViewGroup parent) {
            TextView title;
            ImageView imag;
            View v = view;
            if(v==null){
                //グリットビューの1マス内のレイアウトを作成
                LinearLayout oListLayout = new LinearLayout(mContext);
                //左から右にアイテムを追加
                oListLayout.setOrientation(LinearLayout.HORIZONTAL);
                //イメージビューを生成
                ImageView oImage = new ImageView(mContext);
                //テキストビューを生成
                TextView oText = new TextView(mContext);
                //判別用にタグをつける
                oImage.setTag("CellImage");
                oText.setTag("CellTitle");
                //グリットビュー用のレイアウトに追加
                oListLayout.addView(oImage);
                oListLayout.addView(oText);
                v = oListLayout;
            }
            //配列から、アイテムを取得
            ListItem oList = (ListItem)getItem(position);
            if( dataList != null){
            //タグからテキストビューを取得
            title = (TextView) v.findViewWithTag("CellTitle");
            //取得したテキストビューに文字列を設定
            title.setText(oList.Get_Text());
            //タグからイメージビューを取得
            imag = (ImageView) v.findViewWithTag("CellImage");
            //イメージビューに画像を設定
            imag.setBackgroundResource( oList.Get_Res() );
        }
        return v;
    }
}

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        //押された時のパラメーターを表示
        Toast.makeText(getApplicationContext(), "押下されたのは:" + String.valueOf(position), Toast.LENGTH_SHORT).show();
        Toast.makeText(getApplicationContext(), "IDは:" + String.valueOf(id), Toast.LENGTH_SHORT).show();
    }
}

■ListItemクラス

package com.example.pururun;

public class ListItem {

    private String sText;
    private int    iRes;

    public ListItem(String text, int res){
        //文字列を取得
        sText = text;
        //画像のResIDを取得
        iRes  = res;
    }

    public String Get_Text(){
        //文字列を返す
        return sText;
    }

    public int Get_Res(){
        //画像のResIDを返す
        return iRes;
    }
}


■実行結果


2013年9月24日火曜日

ページめくり(ViewPager, PagerAdapter )

書籍アプリのような、スワイプ操作に対応した画面を作りたい。
Playストアのような画面を作りたい。

そんな時に用いるのがPagerAdapt。。

使い方は簡単で、GridViewやListViewで用いたAdapterを使用します。

昔は外部ライブリを参照しないとViewPagerを使えませんでしたが、
Android3.0以降は外部ライブラリを参照しなくても利用できます。

※android-support-v4.jarで今回のサンプルソースを作成しました。




■サンプルソース
・メインアクティビティ

package com.example.pageadapter;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.support.v4.view.ViewPager;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
      
        // カスタム PagerAdapter を生成
        PagerAdapt oAdp = new PagerAdapt(getApplicationContext());
        oAdp.add(Color.RED);
        oAdp.add(Color.GREEN);
        oAdp.add(Color.WHITE);

        // ViewPager を生成
        ViewPager oViewPager = new ViewPager(getApplicationContext());
        oViewPager.setAdapter(oAdp);
        setContentView(oViewPager);
    }
}

・Adapter用ファイル

package com.example.pageadapter;

import java.util.ArrayList;

import com.example.pageadapter.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.support.v4.view.PagerAdapter;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class PagerAdapt extends PagerAdapter {

    private Context mContext;
    private ArrayList mList;

    //コンストラクター(クラスの生成時に呼ばれる)
    public PagerAdapt(Context context) {
        mContext = context;
        mList = new ArrayList();
    }

    //リストにアイテムを追加する
    public void add(Integer item) {
        mList.add(item);
    }

    //アイテム追加後に呼ばれる
    @Override
    public Object instantiateItem(ViewGroup oVg, int position) {
        // リストから取得
        Integer iColor = mList.get(position);
        //レイアウトを作成
        LinearLayout oLayout = Make_Linear();
        //背景にお色を付ける
        oLayout.setBackgroundColor(iColor);
        oVg.addView(oLayout);
        return oLayout;
    }

    //View を削除
    @Override
    public void destroyItem(ViewGroup oVg, int position, Object object) {
        oVg.removeView((View) object);
    }

    //アイテム数を返す
    @Override
    public int getCount() {
        return mList.size();
    }

    //View が存在するかの判定
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == (LinearLayout) object;
    }
  
    private LinearLayout Make_Linear(){
        //LinearLayoutを生成
        LinearLayout oLayout = new LinearLayout(mContext);
        //縦に格納
        oLayout.setOrientation(LinearLayout.VERTICAL);
        for (int i = 0; i < 4; i++){
            //さらにレイアウトを作成
            LinearLayout oL = new LinearLayout(mContext);
            //横に格納
            oL.setOrientation(LinearLayout.HORIZONTAL);
            oLayout.addView(oL);
            for (int ii = 0; ii < 3; ii++ ){
                //これが最後
                LinearLayout oll = new LinearLayout(mContext);
                //縦に格納
                oll.setOrientation(LinearLayout.VERTICAL);
                //画像とテキストを格納
                oll.addView(Make_ImageView());
                oll.addView(Make_TextView());
                oL.addView(oll);
            }
        }
      
        return oLayout;
    }
  
    private TextView Make_TextView(){
        // TextView を生成
        TextView textView = new TextView(mContext);
        textView.setText("Hello World");
        textView.setTextColor(Color.BLACK);
        textView.setGravity(Gravity.CENTER);
        return textView;
    }

    private ImageView Make_ImageView(){
        // ImageViewを生成
        ImageView oIv = new ImageView(mContext);
        //Bitmapを作成
        Bitmap oBmp = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher);
        //Bitmapをimagviewに貼り付ける
        oIv.setImageBitmap(oBmp);
        return oIv;
    }
}


■実行結果








こんな感じで仕上がります。
何となくViewFlipperみたいな感じがしますが、
ViewFlipperとの違いは階層の深いLayoutを1画面に複数表示できることらしいです。
(本当かどうかはわからない)

2013年9月20日金曜日

layout_weightの設定( setLayoutParams )

weightを設定するとどのように表示されるのかを検証してみました。
基本的にはcssとかで使うときと同じ感覚で使えます。

まずはweightを指定しないとどうなるのか


ソース

package com.jp.layout;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

    private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
     
        oLayout.addView( make_Image(R.drawable.ic_launcher));
        oLayout.addView( make_Image(R.drawable.ic_launcher));
        oLayout.addView( make_Image(R.drawable.ic_launcher));
        oLayout.setOrientation(LinearLayout.HORIZONTAL);
     
        setContentView(oLayout);
    }

    private ImageView make_Image(int ResID){
        ImageView img = new ImageView(getApplicationContext());
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), ResID);
    img.setImageDrawable(getResources().getDrawable(ResID));
    img.setLayoutParams(new LinearLayout.LayoutParams(WC,WC));
    return img;
    }
}



このソースを

package com.jp.layout;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
     
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.setOrientation(LinearLayout.HORIZONTAL);
     
        setContentView(oLayout);
    }

    private ImageView make_Image(int ResID, int weight){
        ImageView img = new ImageView(getApplicationContext());
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), ResID);
    img.setImageDrawable(getResources().getDrawable(ResID));
    img.setLayoutParams(new LinearLayout.LayoutParams(WC, WC, weight));
    return img;
    }
 
    private ImageView make_Image(int ResID){
    ImageView img = new ImageView(getApplicationContext());
    Bitmap bmp = BitmapFactory.decodeResource(getResources(), ResID);
    img.setImageDrawable(getResources().getDrawable(ResID));
    img.setLayoutParams(new LinearLayout.LayoutParams(WC, WC));
    return img;
    }  
}

こんな感じにすると


ちゃんと均等に画像が割り振られていますね。

        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));

この処理で、すべての画像を1:1:1で表示しています。


weightをいじって

        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 1));
        oLayout.addView( make_Image(R.drawable.ic_launcher, 2));

とすると




こんな感じになります。

わかるかな??

ちょっと比率がかわります。

2013年9月5日木曜日

layout_weightをjavaソースで書く(android:layout_weight=)

レイアウトファイルでよく指定する

android:layout_weight="1"

をjavaソースで書く時にどんなメソッドを使うのか、わからなくてなって
ググってもなかなか見つからないことがあるので、メモって見ます。

ちゃんと、覚えないといけないのですが、すぐ忘れてしまって。。。


オブジェクト.setLayoutParams(new LinearLayout.LayoutParams(
  ViewGroup.LayoutParams.MATCH_PARENT,
 ViewGroup.LayoutParams.MATCH_PARENT,
  weight));

setLayoutParamsのnew LinearLayout.LayoutParams()の中の第3引数にweightの
値を入れる

と覚えておこう

つまり

xml でこう書かれているobjectは
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"

javaソースで

private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;

オブジェクト.setLayoutParams(new LinearLayout.LayoutParams(WC,WC, weight));

と記述します。