2012年10月31日水曜日

ActionModeの設定

イメージ長押しでActionModeを設定する

手順
string.xmlの変更
add photo_selection_cab_title
ActionModeのためのメニューを作成する
menuレイアウトの作成
photo_context_menu.xml
ContentFragmentの修正
フィールドの追加
private ActionMode currentActionMode;
private ActionMode.Callback mContentSelectionActionModeCallback
ActionMode.Callbakの作成
onPrepareActionMode
onCreateActionMode
onCreateViewメソッドの修正
setOnLongClickListenreの追加
ActionModeとは
アクションモードは、コンテンツをモーダルインタラクションのために使用され、終了するまで、通常のUIの部分を置き換えることができます。
string.xml
-----------------
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HoneycomicGallery</string>
<string name="photo_selection_cab_title">Photo selection</string>
</resources>
photo_context_menu.xml
---------------------------
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Share" android:icon="?attr/menuIconShare"
android:id="@+id/share" android:showAsAction="always|withText"></item>
</menu>
ContentFragment.java
---------------------------
フィールドの追加
現在のアクションモードとActionModeのコールバックを生成
private ActionMode currentActionMode;
private ActionMode.Callback mContentSelectionActionModeCallback
 ActionMode.Callback の作成
ActionModeのためのコールバックインタフェース
アクションモードとユーザーの相互作用によって発生したイベントを処理します。
onCreateActionMode(ActionMode, Menu)
最初に作成された時だけ呼ばれる
onPrepareActionMode(ActionMode, Menu)
作成後とActionModeになる直前と無効化時に、アクションモードのアクションメニューをリフレッシュするために呼び出されます。
onActionItemClicked(ActionMode, MenuItem)
Actionボタンを押した時
onDestroyActionMode(ActionMode)
AnctionModeを終了するとき
private ActionMode.Callback contentSelectionActionCallback = new
ActionMode.Callback() {

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
contentView.setSelected(false);
currentActionMode = null;
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle(R.string.photo_selection_cab_title);

MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.photo_context_menu, menu);
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.share:
shareCurrentPhoto();
mode.finish();
return true;
}
return false;
}
};

ロングクリック時の処理
contentViewにOnLongClickListenterの実装
ロングクリック時にActionModeを開始する
public ActionMode startActionMode (ActionMode.Callback callback)
ActionModeを開始する
引数にActionModeイベントのコールバックリスナを設定する
// When long-pressing a photo, activate the action mode for
selection, showing the
// contextual action bar (CAB).
contentView.setOnLongClickListener(new
OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
if(currentActionMode != null){
return false;
}
currentActionMode =
getActivity().startActionMode(contentSelectionActionCallback);
contentView.setSelected(true);
return true;
}
});

// TODO change image resource. this operation will be
deleted later.
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.big_droid);
imageView.setImageBitmap(bitmap);

return contentView;
}

実行結果
---------------
long-press a photo

オプションメニューを選択した時の設定
=============================================
選択した画像をシェアする
create method
void shareCurrentPhoto()
create AsyncTask that inner class into the shareCurrentPhoto method.
change onActionItemClicked method
call of share proccess.
change AndroidManifest.xml
add uses-permission
android.permission.WRITE_EXTERNAL_STORAGE


ContentFragment.java
-----------------------------
package com.hidecheck.honeycomic;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnSystemUiVisibilityChangeListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

public class ContentFragment extends Fragment {
private View contentView;

// The bitmap currently used by ImageView
private Bitmap bitmap = null;

// Current action mode (contextual action bar, a.k.a. CAB)
private ActionMode currentActionMode;


@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container, Bundle savedInstanceState) {
contentView = inflater.inflate(R.layout.content_wellcome, null);
final ImageView imageView =
(ImageView)contentView.findViewById(R.id.image);
contentView.setDrawingCacheEnabled(false);

// TODO setting DragListener later

// Keep the action bar visibility in sync with the system status
bar. That is, when entering
// 'lights out mode,' hide the action bar, and when exiting this
mode, show the action bar.
final Activity activity = getActivity();
contentView.setOnSystemUiVisibilityChangeListener(new
OnSystemUiVisibilityChangeListener() {

@Override
public void onSystemUiVisibilityChange(int visibility) {
ActionBar actionBar = activity.getActionBar();
if(actionBar != null){
contentView.setSystemUiVisibility(visibility);
if(visibility == View.STATUS_BAR_VISIBLE){
actionBar.show();
}else{
actionBar.hide();
}
}
}
});

contentView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if(contentView.getSystemUiVisibility() ==
View.STATUS_BAR_VISIBLE){
contentView.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
}else{
contentView.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
}
}
});

// When long-pressing a photo, activate the action mode for
selection, showing the
// contextual action bar (CAB).
contentView.setOnLongClickListener(new OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
if(currentActionMode != null){
return false;
}
currentActionMode =
getActivity().startActionMode(contentSelectionActionCallback);
contentView.setSelected(true);
return true;
}
});

// TODO change image resource. this operation will be deleted
later.
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.big_droid);
imageView.setImageBitmap(bitmap);

return contentView;
}

void shareCurrentPhoto() {
File externalCacheDir = getActivity().getExternalCacheDir();
if(externalCacheDir == null){
Toast.makeText(getActivity(), "Error writing to USB/external
storage.", Toast.LENGTH_SHORT).show();
return;
}

// Prevent media scanning of the cache directory.
final File noMediaFile = new File(externalCacheDir, ".nomedia");
try{
noMediaFile.createNewFile();
}catch (IOException e) {
Log.e(getClass().getName(), "shareCurrentPhoto", e);
}

// Write the bitmap to temporary storage in the external storage
directory (e.g. SD card).
// We perform the actual disk write operations on a separate
thread using the
// {@link AsyncTask} class, thus avoiding the possibility of
stalling the main (UI) thread.

final File tempFile = new File(externalCacheDir,
"tempfile.jpg");

new AsyncTask<Void, Void, Boolean>(){

/**
* Compress and write the bitmap to disk on a separate
thread.
* @return TRUE if the write was successful, FALSE
otherwise.
*/
@Override
protected Boolean doInBackground(Void... params) {

try{
FileOutputStream fo = new FileOutputStream(tempFile,
false);
if(!bitmap.compress(Bitmap.CompressFormat.JPEG, 60,
fo)){
Toast.makeText(getActivity(), "Error writing
bitmap data.", Toast.LENGTH_SHORT).show();
return Boolean.FALSE;
}
return Boolean.TRUE;
}catch (FileNotFoundException e) {
Toast.makeText(getActivity(), "Error writing to
USB/external storage.", Toast.LENGTH_SHORT).show();
return Boolean.FALSE;
}
}

/**
* After doInBackground completes (either successfully or in
failure), we invoke an
* intent to share the photo. This code is run on the main
(UI) thread.
*/
@Override
protected void onPostExecute(Boolean result) {
if(result != Boolean.TRUE){
return;
}

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM,
Uri.fromFile(tempFile));
shareIntent.setType("image/jpeg");
startActivity(Intent.createChooser(shareIntent, "Share
photo"));
}
}.execute();
}

private ActionMode.Callback contentSelectionActionCallback = new
ActionMode.Callback() {

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
contentView.setSelected(false);
currentActionMode = null;
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle(R.string.photo_selection_cab_title);

MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.photo_context_menu, menu);
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem
item) {
switch (item.getItemId()) {
case R.id.share:
shareCurrentPhoto();
mode.finish();
return true;
}
return false;
}
};
}
AndroidManifest.xml
----------------------
sdcardの書き込みを有効にする
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

0 件のコメント:

コメントを投稿