ListViewで表示された画面の上でフリック動作をしたいのですが、出来ません。

2,255 views
Skip to first unread message

autumn

unread,
Apr 7, 2011, 3:40:27 AM4/7/11
to 日本Androidの会
はじめまして。autumnと申します。
最近Androidのアプリの勉強を行っています。

(※かなり曖昧な記述になってしまうと思われますが、なにとぞご容赦ください)

現在、データベースから読み込んだ種々のデータをListViewにて画面でリスト表示し、
そのリスト上で横向きのフリック動作
(横にスパッと指を動かす動作です、スワイプ?でもいいのでしょうか)を行うと、
次のデータを検索しにいく、という動作をしたいのですが、
ListView上でのフリック動作がまったく認識されません。

メインとなるActivityにてgestureDetectorを呼出して、onFling時に動作を実行させようとしていますが
なぜか、ListViewの部分は完全に無視され、リストのタイトルに作っているtablelayout部だけが
gestureDetectorの対象になっています。
また、そちらのgestureDetectorでもonFlingのイベントは捕まらず、
(ためしに イベントが走ったときLog.v("Test", "onFling()"); としていますが、ログは表示されているのに
ここにEclipse上でブレークポイントを置いても引っかかりませんでした。なぜ?)


なお、そのListViewを置いているlayoutの構造はこうしていました

[LinearLayout]
|
|----[画面タイトル(textview)]  ←  ここはGestureDetectorが効く
|
|----[テーブル(Tablelayout)   ←  ここはGestureDetectorが効く
| |
| |-----[TableRow]
| |
| |----[タイトル1]
| |----[タイトル2]
| |----[タイトル3]
|----[DB値(ListView)]      ←  反応しない

なお、ListViewの中はTextViewを単純に3つ横へ並べただけで、
これ自体の表示はうまくいっています。

まだ参考書といえるような参考書もなく、英語もはっきり読解できませんので、
この状態でフリック動作ができるようネットのあちこちを探索しているのですが、
これだ! と言えるような記述もなく、困っています。

なにとぞお知恵をお貸しいただければ幸いです。それでは失礼します。

autumn

unread,
Apr 7, 2011, 4:27:17 AM4/7/11
to 日本Androidの会
autumnです、すみません。
肝心のActivity内のコードを記載していませんでした。
このコード自体、あちこちからコピーしたり生半可に弄っただけなので、すごい勘違いをしているかもしれません・・・
宜しくお願いします。

package com.example.autumn.hsp;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ViewFlipper;

// Activity "Hellodb"の開始
public class Hellodb extends Activity implements
GestureDetector.OnGestureListener, // 長押し(onLongPress)のイベントが取得できます。
GestureDetector.OnDoubleTapListener // ダブルタップのイベントが取得できます。
{

// 画面上、ページ表題
private int pages; // 遷移元のページ番号
private int MaxPage; // 最大ページ

// リストビューを設定する
private ArrayList<Dataset> PageItems = new ArrayList<Dataset>();
/** GestureDetectorを定義する */
private GestureDetector GD;

private ListView lv;

/** 開始時処理 */
@Override
public void onCreate(Bundle savedInstanceState)
{
// スーパークラス継承
super.onCreate(savedInstanceState);
// layout呼出
setContentView(R.layout.main);

// GestureDetector設定
// このクラス(TestGesture)をリスナーとして設定
this.GD = new GestureDetector(this,this);

// 前画面からのインテントを取得
MaxPage = getIntent().getIntExtra("MaxP",0);
int number_P = getIntent().getIntExtra("PAGE",0); // 遷移フリック時に渡さ
れる保持番号
int number_N = getIntent().getIntExtra("NEXT",0); // 次画面遷移フリック時
に渡されるインテント
int number_B = getIntent().getIntExtra("BACK",0); // 前画面遷移フリック時
に渡されるインテント

// 遷移元画面のカルテ番号始点
if (number_P != 0){
pages = number_P;
}
// 次画面フリック時
if (number_N != 0){
// 現在ページの算出
pages = pages + 1;
}
// 前画面フリック時
if (number_B != 0){
// 現在ページの算出
pages = pages - 1;
}

// リストビューの設定
lv = (ListView) findViewById(R.id.ListRow);

// グローバル配列より変数の切り出し(PageItemsに格納)
for (int i = 0;i <= 50;i++)
{
// 取得したデータのインデックスを超えた場合処理を中止する
if ((((pages - 1) * 50) + i) >= GlobalData.PDataArray.size() )
break;

// 取得したデータのインデックスよりデータを追加
PageItems.add(GlobalData.PDataArray.get(((pages - 1) * 50) + i ));
}

// ListAdapterの設定を行う
ListAdapter adapter = new ListAdapter(this,R.id.ListRow,PageItems);
lv.setAdapter(adapter);
}

// 読み込んだDBデータ用のリストアダプタ
public class ListAdapter extends ArrayAdapter<Dataset> {

private LayoutInflater inflater;
private ArrayList<Dataset> items = new ArrayList<Dataset>();

// コンストラクタ。内容は不明?
public ListAdapter( Context context,
int textViewResourceId,
ArrayList<Dataset> TblKihon)
{
super(context, textViewResourceId, TblKihon);

this.items = TblKihon;
this.inflater =
(LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

//操作対象のViewを見る
//完全に新規に作る場合はnullがわたってくる
@Override
public View getView(int position, View convertView, ViewGroup
parent) {

View v = convertView;
if(v == null){
//1行分layoutからViewの塊を生成
v = inflater.inflate(R.layout.listrow, null);
}
//itemsからデータ
//vから画面にくっついているViewを取り出して値をマッピングする
Dataset dt = (Dataset)items.get(position);

// 1列目(番号)
TextView Text1 = (TextView)v.findViewById(R.id.Text1);
Text1.setText((String) dt.getNo());
// 2列目(漢字氏名)
TextView Text2 = (TextView)v.findViewById(R.id.Text2);
Text2.setText((String) dt.getKName());
// 3列目(生年月日)
TextView Text3 = (TextView)v.findViewById(R.id.Text3);
Text3.setText((String) dt.getBirth());

return v;
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if (GD.onTouchEvent(event)) {
return true;
}
// 設定したGestureDetectorにイベントを持たせる。
return super.onTouchEvent(event);
}

// *************
// 以下動作確認中
// *************

@Override
// ダブルタップ時のイベント
public boolean onDoubleTap(MotionEvent e) {
Log.v("Test", "onDoubleTap()");
return false;
}

@Override
public boolean onDoubleTapEvent(MotionEvent e) { // ダブルタップ後のイベント
Log.v("Test", "onDoubleTapEvent()");
return false;
}

@Override
// タップしてから指が離れた後のイベント
// onLongPressと重複しない
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.v("Test", "onSingleTapConfirmed()");
return false;
}

@Override
public boolean onDown(MotionEvent arg0) { // タップした瞬間のイベント(シングルタップ)
// TODO 自動生成されたメソッド・スタブ
Log.v("Test", "onDown()");
return false;
}

@Override
public boolean onFling(MotionEvent e1, // フリック時のイベント
MotionEvent e2,
float velocityX,
float velocityY)
{
// TODO 自動生成されたメソッド・スタブ
Log.v("Test", "onFling()");

// 左にフリックした場合、次データとアクティビティを処理
if (e1.getX() > e2.getX() & pages >= MaxPage) {

// 現在のアクティビティを破棄
finish();
// インテントの作成
Intent it =new Intent();
// インテントがどのアクティビティ間で発生するかを指定
it.setClass(getApplicationContext(), Next.class);
// インテントに遷移データをセット(+1)
it.putExtra("MaxP", MaxPage);
it.putExtra("PAGE", pages);
it.putExtra("NEXT", 1);
// インテント(および画面遷移)開始
startActivity(it);
}

// 右にフリックした場合、前データとアクティビティを処理
if (e1.getX() < e2.getX() & pages != 1) {

// 現在のアクティビティを破棄
finish();
// インテントの作成
Intent it =new Intent();
// インテントがどのアクティビティ間で発生するかを指定
it.setClass(getApplicationContext(), Next.class);
// インテントに遷移データをセット(-1)
it.putExtra("MaxP", MaxPage);
it.putExtra("PAGE", pages);
it.putExtra("BACK", -1);
// インテント(および画面遷移)開始
startActivity(it);
}

// なにもしない
return true;
}

@Override
public void onLongPress(MotionEvent e) { // 長押し時のイベント
// TODO 自動生成されたメソッド・スタブ
Log.v("Test", "onLongPress()");
}

@Override
public boolean onScroll(MotionEvent e1, // 各種方向フリック
MotionEvent e2,
float distanceX,
float distanceY) {
// TODO 自動生成されたメソッド・スタブ
Log.v("Test", "onScroll()");
return false;
}

@Override
public void onShowPress(MotionEvent e) { // 通常押し時のイベント
// TODO 自動生成されたメソッド・スタブ
Log.v("Test", "onShowPress()");
}

@Override
public boolean onSingleTapUp(MotionEvent e) { // タップ後指が離れた時のイベント
// TODO 自動生成されたメソッド・スタブ // onLongPressと重複しない)
Log.v("Test", "onSingleTapUp()");
return false;
}
}

mitsukaido

unread,
Apr 7, 2011, 8:07:24 AM4/7/11
to android-g...@googlegroups.com
listview上のlistadapter上のアイテムがイベントを消費しています。
カスタムlistadapterでアイテムにgesturedetectorを作成したりしてみてはいかがでしょうか。

autumn

unread,
Apr 7, 2011, 10:34:14 PM4/7/11
to 日本Androidの会
お返事有難うございます。
なにぶんJAVAもAndroidも初心者なもので、
ちょっとこれから手をつけて、動作確認するまで時間かかると思いますが
なんとかその方向でやってみたいと思います。


On 4月7日, 午後9:07, mitsukaido <yanag...@gmail.com> wrote:
> listview上のlistadapter上のアイテムがイベントを消費しています。
> カスタムlistadapterでアイテムにgesturedetectorを作成したりしてみてはいかがでしょうか。
Reply all
Reply to author
Forward
0 new messages