xmlファイルを使わずにFragmentを生成する方法(´・ω・`)?


xmlを使わずにFragmentを生成する方法をぐぐっていて、ヒットした
android – How to programmatically create the layout for a Fragment?
android – How do I add a Fragment to an Activity with a programmatically created content view
を参考にコードをでっち上げたが、果たしてこれで正しいのかどうかよくわからないw

そもそもなんでそんなことをしようしたのかというと、前のエントリを確認している時に
LongClickを拾えなくなった時に「前に試したコードはListFragmentだったから、それと
一緒にしないと再現できないのか…( ;・´ω・`)ゴクリッ?」という勘違いをして、かつ、
「サンプルコードはワンストップならぬワンコピペで完結すべき(`・ω・´)」という
謎の思想から、xmlファイルによるレイアウト指定を無しにしたいと思ったから(ノ∀`)

一応これで出来てるみたいだけれども、実際にプログラムの一部として使うには
もっと何かをしないといけないのかもしれないが、その辺はよくわからないw

取り敢えずワンコピペで試せるFragmentを使用するサンプルを作るのには
利用出来るので、これはこれでいいかな。

なぜかLongClickでToastが表示出来ないのは謎(´・ω・`)
Log.dには出力されているのに。まあタッチイベント関連はこのサンプルの
本質とは全く関係ないのだけれどw

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private GestureDetector mGestureDetector;
	private View.OnTouchListener mGestureListener;
	private static final int CONTENT_VIEW_ID = 10101010;
	private static final String[] CONFECTIONERY = {
		"Apple Pie", "Banana Bread", "Cupcake", "Donut", "Eclair", "Froyo",
		"Gingerbread", "Honeycomb", "Ice Cream Sandwich", "Jelly Bean",
		"KitKat", "Lollipop"
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		LinearLayout layout=new LinearLayout(this);
		layout.setBackgroundColor(Color.WHITE);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setId(CONTENT_VIEW_ID);

		setContentView(layout, new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

		Bundle bundle = new Bundle();
		bundle.putStringArray("confectionery", CONFECTIONERY);

		if (savedInstanceState == null) {
			Fragment newFragment = new MyFragment();
			FragmentTransaction ft = getFragmentManager().beginTransaction();
			ft.add(CONTENT_VIEW_ID, newFragment).commit();
		}
	}

	private void myOnItemClick(int position) {
		Log.d("myOnItemClick", "itemClick: " + position);
		Toast.makeText(MainActivity.this, "myOnItemClick itemClick" + position, Toast.LENGTH_LONG).show();
	}

	public class MyFragment extends Fragment {

		public MyFragment() {}

		View rootView;
		ListView listView;
		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
			LinearLayout layout=new LinearLayout(getActivity());
			Log.d("MyFragment", "onCreateView");
			layout.setOrientation(LinearLayout.VERTICAL);

			listView = new ListView(getActivity());

			listView.setLayoutParams(new LinearLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,
					CONFECTIONERY));

			layout.addView(listView);

			rootView = layout;
			rootView.setBackgroundColor(Color.WHITE);
			return rootView;
		}

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

			mGestureDetector = new GestureDetector(getActivity(),new MyGestureDetector());
			mGestureListener = new View.OnTouchListener() {
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					return mGestureDetector.onTouchEvent(event);
				}
			};

			listView.setOnTouchListener(mGestureListener);
			listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
				@Override
				public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
					Log.d("onItemLongClick", "LongClick");
					Toast.makeText(MainActivity.this, "onItemLongClick LongClick", Toast.LENGTH_LONG).show();
					return true;
				}
			});
		}

		class MyGestureDetector extends SimpleOnGestureListener {
			private static final int SWIPE_MIN_DISTANCE = 120;
			private static final int SWIPE_MAX_OFF_PATH = 250;
			private static final int SWIPE_THRESHOLD_VELOCITY = 200;

			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				int pos = listView.pointToPosition((int)e.getX(), (int)e.getY());
				myOnItemClick(pos);
				return false;
			}

			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2,
					float velocityX, float velocityY) {
				if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
					return false;
				}

				boolean isDoCancel = false;

				if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
					Log.d("onFling", "FlingLeft");
					Toast.makeText(MainActivity.this, "onFling FlingLeft", Toast.LENGTH_LONG).show();

					isDoCancel = true;

				} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
					Log.d("onFling", "FlingRight");
					Toast.makeText(MainActivity.this, "onFling FlingRight", Toast.LENGTH_LONG).show();

					isDoCancel = true;
				}

				if(isDoCancel){
					MotionEvent cancelEvent = MotionEvent.obtain(e2);
					cancelEvent.setAction(MotionEvent.ACTION_UP);
					listView.onTouchEvent(cancelEvent);
					return true;
				}else{
					return false;
				}

			}
		}
	}
}