2010年11月7日日曜日

Android Quick Action の Android ライブラリプロジェクトを作ってみた

Google I/O の UI design pattern で紹介されていた、Quick Action (twitter アプリや Gmail アプリで使われている) は標準の SDK の中にはありません。

# Quick Action については以前のエントリ「Android UI Design Tips」でも簡単にかきました。

leibun さんのブログのエントリがわかりやすいです。
QuickActionの使い方 - leibunのテクニカルブログ -

leibun さんのブログでも紹介されてますが、
 ・http://code.google.com/p/simple-quickactions/
 ・http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/

とかでソースが公開されています。

http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/ のコードを落としてきてアプリにソースや画像をコピーしてもいいのですが、コピーするの面倒だし、2つのスタイルが別々になっているし、一つのアプリで複数のスタイルの QuickAction を使えないし、Trackアニメーションを設定できないので fork してみました。

 サンプル apk はこちら

 ・スタイルを twitter 公式アプリの QuickAction っぽいの
  or シンプルなポップアップ から選択可能
 ・外枠用の layout リソースIDを指定可能
 ・中の item 用の layout リソースIDを指定可能
 ・Track アニメーションの interpolator の指定が可能












https://github.com/yanzm/QuickActionLib からダウンロードして、Eclipse に Import します。QuickActionLib の Properties で [Android] - [Library] の Is Library をチェックし、Android ライブラリプロジェクトにします。




使う方では、プロジェクトの Properties で [Android] - [Library] - [Add] から QuickActionLib を追加






こんな感じで使う

  1. package yanzm.example.quickactiontest2;  
  2.   
  3. import yanzm.products.quickaction.lib.ActionItem;  
  4. import yanzm.products.quickaction.lib.QuickAction;  
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.Toast;  
  11.   
  12. public class QuickActionTest2 extends Activity {  
  13.   
  14.  @Override  
  15.  public void onCreate(Bundle savedInstanceState) {  
  16.   super.onCreate(savedInstanceState);  
  17.   setContentView(R.layout.main);  
  18.   
  19.     
  20.   // 1st item  
  21.   final ActionItem chart = new ActionItem();  
  22.     
  23.   chart.setTitle("Chart");  
  24.   chart.setIcon(getResources().getDrawable(R.drawable.chart));  
  25.   chart.setOnClickListener(new OnClickListener() {  
  26.    @Override  
  27.    public void onClick(View v) {  
  28.     Toast.makeText(QuickActionTest2.this"Chart selected" , Toast.LENGTH_SHORT).show();  
  29.    }  
  30.   });  
  31.     
  32.     
  33.   // 2nd item  
  34.   final ActionItem production = new ActionItem();  
  35.     
  36.   production.setTitle("Products");  
  37.   production.setIcon(getResources().getDrawable(R.drawable.production));  
  38.   production.setOnClickListener(new OnClickListener() {  
  39.    @Override  
  40.    public void onClick(View v) {  
  41.     Toast.makeText(QuickActionTest2.this"Products selected", Toast.LENGTH_SHORT).show();  
  42.    }  
  43.   });  
  44.     
  45.     
  46.   // 3rd item  
  47.   final ActionItem budget = new ActionItem();  
  48.     
  49.   budget.setTitle("Budget");  
  50.   budget.setIcon(getResources().getDrawable(R.drawable.budget));  
  51.   budget.setOnClickListener(new OnClickListener() {  
  52.    @Override  
  53.    public void onClick(View v) {  
  54.     Toast.makeText(QuickActionTest2.this"Budget selected", Toast.LENGTH_SHORT).show();  
  55.    }  
  56.   });  
  57.   
  58.   // 4th item  
  59.   final ActionItem dashboard = new ActionItem();  
  60.     
  61.   dashboard.setIcon(getResources().getDrawable(R.drawable.dashboard));  
  62.   dashboard.setOnClickListener(new OnClickListener() {  
  63.    @Override  
  64.    public void onClick(View v) {  
  65.     Toast.makeText(QuickActionTest2.this"dashboard selected" , Toast.LENGTH_SHORT).show();  
  66.    }  
  67.   });  
  68.     
  69.     
  70.   // 5th item  
  71.   final ActionItem users = new ActionItem();  
  72.     
  73.   users.setIcon(getResources().getDrawable(R.drawable.users));  
  74.   users.setOnClickListener(new OnClickListener() {  
  75.    @Override  
  76.    public void onClick(View v) {  
  77.     Toast.makeText(QuickActionTest2.this"Products selected", Toast.LENGTH_SHORT).show();  
  78.    }  
  79.   });  
  80.     
  81.     
  82.   // Default Setting  
  83.   Button btn1 = (Button) this.findViewById(R.id.btn1);  
  84.   btn1.setText("Default Setting");  
  85.   btn1.setOnClickListener(new View.OnClickListener() {  
  86.    @Override  
  87.    public void onClick(View v) {  
  88.     QuickAction qa = new QuickAction(v);  
  89.       
  90.     qa.addActionItem(chart);  
  91.     qa.addActionItem(production);  
  92.       
  93.     qa.show();  
  94.    }  
  95.   });  
  96.     
  97.   // ANIM_AUTO  
  98.   Button btn2 = (Button) this.findViewById(R.id.btn2);  
  99.   btn2.setText("QuickAction.ANIM_AUTO\nmany Items");  
  100.   btn2.setOnClickListener(new View.OnClickListener() {  
  101.    @Override  
  102.    public void onClick(View v) {  
  103.     QuickAction qa = new QuickAction(v);  
  104.       
  105.     qa.addActionItem(chart);  
  106.     qa.addActionItem(production);  
  107.     qa.addActionItem(chart);  
  108.     qa.addActionItem(production);  
  109.     qa.addActionItem(chart);  
  110.     qa.addActionItem(production);  
  111.     qa.addActionItem(chart);  
  112.     qa.addActionItem(production);  
  113.     qa.setAnimStyle(QuickAction.ANIM_AUTO);  
  114.       
  115.     qa.show();  
  116.    }  
  117.   });  
  118.      
  119.     
  120.   // ANIM_GROW_FROM_CENTER  
  121.   Button btn3 = (Button) this.findViewById(R.id.btn3);  
  122.   btn3.setText("QuickAction.ANIM_GROW_FROM_CENTER\nItems have no title\nNo Interpolator");  
  123.   btn3.setOnClickListener(new OnClickListener() {  
  124.    @Override  
  125.    public void onClick(View v) {  
  126.     QuickAction qa = new QuickAction(v);  
  127.       
  128.     qa.addActionItem(dashboard);  
  129.     qa.addActionItem(users);  
  130.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_CENTER);  
  131.     qa.setAnimTrack(R.anim.rail2, null);  
  132.       
  133.     qa.show();  
  134.    }  
  135.   });  
  136.   
  137.   // ANIM_GROW_FROM_CENTER  
  138.   Button btn4 = (Button) this.findViewById(R.id.btn4);  
  139.   btn4.setText("QuickAction.ANIM_GROW_FROM_LEFT\nItems have no title\nNo Track Animation");  
  140.   btn4.setOnClickListener(new OnClickListener() {  
  141.    @Override  
  142.    public void onClick(View v) {  
  143.     QuickAction qa = new QuickAction(v);  
  144.       
  145.     qa.addActionItem(dashboard);  
  146.     qa.addActionItem(users);  
  147.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_LEFT);  
  148.     qa.setAnimTrackEnabled(false);  
  149.       
  150.     qa.show();  
  151.    }  
  152.   });  
  153.   
  154.   // ANIM_GROW_FROM_CENTER  
  155.   Button btn5 = (Button) this.findViewById(R.id.btn5);  
  156.   btn5.setText("QuickAction.ANIM_GROW_FROM_RIGHT");  
  157.   btn5.setOnClickListener(new OnClickListener() {  
  158.    @Override  
  159.    public void onClick(View v) {  
  160.     QuickAction qa = new QuickAction(v);  
  161.       
  162.     qa.addActionItem(chart);  
  163.     qa.addActionItem(users);  
  164.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_RIGHT);  
  165.       
  166.     qa.show();  
  167.    }  
  168.   });  
  169.     
  170.   // ANIM_GROW_FROM_CENTER  
  171.   Button btn6 = (Button) this.findViewById(R.id.btn6);  
  172.   btn6.setText("QuickAction.ANIM_REFLECT");  
  173.   btn6.setOnClickListener(new OnClickListener() {  
  174.    @Override  
  175.    public void onClick(View v) {  
  176.     QuickAction qa = new QuickAction(v);  
  177.       
  178.     qa.addActionItem(dashboard);  
  179.     qa.addActionItem(users);  
  180.     qa.setAnimStyle(QuickAction.ANIM_REFLECT);  
  181.     qa.setLayoutStyle(QuickAction.STYLE_BUTTON);  
  182.       
  183.     qa.show();  
  184.    }  
  185.   });  
  186.     
  187.     
  188.       
  189.   //////////////////////////////////////////////////////  
  190.   
  191.   // Default Setting + STYLE_LIST  
  192.   Button btn7 = (Button) this.findViewById(R.id.btn7);  
  193.   btn7.setText("QuickAction.STYLE_LIST");  
  194.   btn7.setOnClickListener(new View.OnClickListener() {  
  195.    @Override  
  196.    public void onClick(View v) {  
  197.     QuickAction qa = new QuickAction(v);  
  198.       
  199.     qa.addActionItem(chart);  
  200.     qa.addActionItem(production);  
  201.     qa.setLayoutStyle(QuickAction.STYLE_LIST);  
  202.       
  203.     qa.show();  
  204.    }  
  205.   });  
  206.     
  207.   // ANIM_AUTO  
  208.   Button btn8 = (Button) this.findViewById(R.id.btn8);  
  209.   btn8.setText("QuickAction.ANIM_AUTO\nQuickAction.STYLE_LIST with Constractor");  
  210.   btn8.setOnClickListener(new View.OnClickListener() {  
  211.    @Override  
  212.    public void onClick(View v) {  
  213.     QuickAction qa = new QuickAction(v, R.layout.popup2, QuickAction.STYLE_LIST);  
  214.       
  215.     qa.addActionItem(chart);  
  216.     qa.addActionItem(production);  
  217.     qa.setAnimStyle(QuickAction.ANIM_AUTO);  
  218.       
  219.     qa.show();  
  220.    }  
  221.   });  
  222.     
  223.   // ANIM_GROW_FROM_CENTER  
  224.   Button btn9 = (Button) this.findViewById(R.id.btn9);  
  225.   btn9.setText("QuickAction.ANIM_GROW_FROM_CENTER\nQuickAction.STYLE_LIST\nsetItemLayoutId()");  
  226.   btn9.setOnClickListener(new OnClickListener() {  
  227.    @Override  
  228.    public void onClick(View v) {  
  229.     QuickAction qa = new QuickAction(v);  
  230.       
  231.     qa.addActionItem(dashboard);  
  232.     qa.addActionItem(users);  
  233.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_CENTER);  
  234.     qa.setLayoutStyle(QuickAction.STYLE_LIST);  
  235.     qa.setItemLayoutId(R.layout.action_item);  
  236.       
  237.     qa.show();  
  238.    }  
  239.   });  
  240.   
  241.   // ANIM_GROW_FROM_CENTER  
  242.   Button btn10 = (Button) this.findViewById(R.id.btn10);  
  243.   btn10.setText("QuickAction.ANIM_GROW_FROM_LEFT");  
  244.   btn10.setOnClickListener(new OnClickListener() {  
  245.    @Override  
  246.    public void onClick(View v) {  
  247.     QuickAction qa = new QuickAction(v);  
  248.       
  249.     qa.addActionItem(budget);  
  250.     qa.addActionItem(production);  
  251.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_LEFT);  
  252.     qa.setLayoutStyle(QuickAction.STYLE_LIST);  
  253.     qa.setItemLayoutId(R.layout.action_item2);  
  254.       
  255.     qa.show();  
  256.    }  
  257.   });  
  258.   
  259.   // ANIM_GROW_FROM_CENTER  
  260.   Button btn11 = (Button) this.findViewById(R.id.btn11);  
  261.   btn11.setText("QuickAction.ANIM_GROW_FROM_RIGHT\ncustom layout");  
  262.   btn11.setOnClickListener(new OnClickListener() {  
  263.    @Override  
  264.    public void onClick(View v) {  
  265.     QuickAction qa = new QuickAction(v, R.layout.popup2, QuickAction.STYLE_LIST);  
  266.       
  267.     qa.addActionItem(budget);  
  268.     qa.addActionItem(production);  
  269.     qa.setAnimStyle(QuickAction.ANIM_GROW_FROM_RIGHT);  
  270.     qa.setItemLayoutId(R.layout.action_item3);  
  271.       
  272.     qa.show();  
  273.    }  
  274.   });  
  275.     
  276.   // ANIM_GROW_FROM_CENTER  
  277.   Button btn12 = (Button) this.findViewById(R.id.btn12);  
  278.   btn12.setText("QuickAction.ANIM_REFLECT");  
  279.   btn12.setOnClickListener(new OnClickListener() {  
  280.    @Override  
  281.    public void onClick(View v) {  
  282.     QuickAction qa = new QuickAction(v);  
  283.       
  284.     qa.addActionItem(dashboard);  
  285.     qa.addActionItem(users);  
  286.     qa.setAnimStyle(QuickAction.ANIM_REFLECT);  
  287.     qa.setLayoutStyle(QuickAction.STYLE_LIST);  
  288.       
  289.     qa.show();  
  290.    }  
  291.   });    
  292.  }  
  293. }  

 

 

5 件のコメント:

  1. Thank you very much for the lib. It is very useful.

    I just added a small functionality to the file QuickAction.java. Now one can set the popup to be ABOVE, BELOW or as OVERLAY:
    quickAction.setPosition(QuickAction.POSITION_BELOW);

    If you want I am willing to share it with you so you can add it to the library so that other people can use it.

    you can contact me over: pboos at tonchidot.com (replace at with @)

    Regards,
    Patrick Boos

    返信削除
  2. 端末を横向きにした状態でQuick Actionを呼び出すと、QuickActionクラスのshowListStyleメソッドの329行目や338行目でインスタンスフィールドscrollerを参照してNullPointerExceptionが発生します。

    修正していただけないでしょうか?

    よろしくお願いいたします。

    返信削除
  3. 書き忘れましたが、NullPointerExceptionが発生するのは、レイアウトスタイルがリストスタイルの場合です。

    よろしくお願いいたします。

    返信削除
  4. Você é do caralho maninho!!!!!!!!!!!

    muito bom mesmo, sou seu fã!!!!

    Você é zica do pantano!!!!

    http://www.astraclub.com.br/forum/style_emoticons/default/smile_venerando.gif

    返信削除
  5. QuickAction便利に使わせていただいております。
    kinmojrさんのコメントと同様の原因だと思いますが、リストスタイルの場合、QuickActionのポップアップが画面をはみ出るとNullPointerExceptionが発生します。

    QuickAction.java 193行目を以下のように修正して使用しています。
    【オリジナル】scroller = null;

    【修正】scroller = (ScrollView) rootView.findViewById(R.id.scroller);

    また、ダイアログ上のViewに対してで使用すると吹き出しの位置がずれるので、修正してみようと思います。

    返信削除