2011-10-25 8 views
1

TouchListViewコンポーネントを変更して、アイテムをリストビューから別のビューにドラッグしてドラッグアンドドロップ選択システムを作成できるようにしようとしています。ユーザーはリスト項目をドラッグしてリリースし、選択項目を示します。TouchListビューをリストから別のビュー(画像ビュー)にドラッグする修正

これまで、DropListenerクラスのonDropメソッドを変更して、MotionEventを渡しました。また、私は、ユーザーがドラッグしたビューをイメージビューにドロップしたかどうかを判断するためにも、動きのgetY()メソッドを使用しています。私はgetY()の生の値を使用していますが、それが-50より小さい場合、それを有効な値として受け入れています。

しかし、これはむしろクルージングな解決策であり、エラーが発生する可能性があると私は懸念しています。ユーザーがターゲットビュー領域を解放したときを判断する良い方法はありますか?私は単純に負の数を探すことができない場合がありますか? X/Y座標のセットの下に実際にどのようなビューがあるのか​​を実際に確認する方法はありますか?

進行中のレイアウトの添付図に注意してください。

enter image description here

+0

私はこれを試したことはありませんが、各ウィジェットの 'getLocationInWindow()'は、比較のための一貫した座標セットを与えるはずです。原則として、 '-50'と組み合わせてそれを使って、' -50'があなたのターゲットウィジェット上にあるかどうかを判断することができます。 – CommonsWare

+0

ありがとうございます!それがそれでした。この場合、DropListenerとDrag listenerのMotionEventへの参照を渡すと、ドラッグされたビューがターゲット上にあるときにドロップターゲットを強調表示するなど、インタラクションを非常にうまくできました。 –

+0

うれしかった!あなたが私に送ることができるいくつかのサンプルコードがあるなら、 'TouchListView'の' README'の一部としてこれを書いておきたいと思います。 – CommonsWare

答えて

1

ここで私はそれが働いていた思い付いたソリューションです。

package com.commonsware.cwac.tlv.demo; 

import java.util.ArrayList; 
import java.util.Arrays; 

import android.app.ListActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.ViewTreeObserver; 
import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.commonsware.cwac.tlv.TouchListView; 

public class TouchListViewDemo extends ListActivity { 
    private static String[] items={"lorem", "ipsum", "dolor", "sit", "amet", 
                    "consectetuer", "adipiscing", "elit", "morbi", "vel", 
                    "ligula", "vitae", "arcu", "aliquet", "mollis", 
                    "etiam", "vel", "erat", "placerat", "ante", 
                    "porttitor", "sodales", "pellentesque", "augue", "purus"}; 
    private TouchListView tlv; 
    private IconicAdapter adapter=null; 
    private ArrayList<String> array=new ArrayList<String>(Arrays.asList(items)); 

    private TextView target_name_display; 
    private ImageView target; 

    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     setContentView(R.layout.main); 

     tlv = (TouchListView)getListView(); 
     adapter=new IconicAdapter(); 
     setListAdapter(adapter); 

     tlv.setDropListener(onDrop); 
     tlv.setRemoveListener(onRemove); 


     target = (ImageView) findViewById(R.id.drag_target_area); 
     target_name_display = (TextView) findViewById(R.id.name_text); 
     Log.d("TARGET", "Target:"+target); 
     Log.d("TARGET", "TargeName Displayt:"+target_name_display); 


     ViewTreeObserver vto = target.getViewTreeObserver(); 
     vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 

      @Override 
      public void onGlobalLayout() { 
       target.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
       int height = target.getHeight(); 
       int top = target.getTop(); 
       int tlv_y_position = tlv.getTop(); 
       Log.d("ON LAYOUT", "Height:"+ height+ " top:"+top+" tlv_y_position:"+tlv_y_position);    
      } 
     }); 

    } 

    private TouchListView.DropListener onDrop=new TouchListView.DropListener() { 
     @Override 
     public void drop(int from, int to, MotionEvent e) { 
      Log.i("TOUCH VIEW DEMO", "From: "+from + " TO: "+to); 
      Log.i("TOUCH VIEW DEMO", "Event: "+e.getY()); 
       String item=adapter.getItem(from); 

       // 
       int[] target_coords = new int[2]; 
       int[] tlv_coords = new int[2]; 
       target.getLocationInWindow(target_coords); 
       tlv.getLocationInWindow(tlv_coords); 
       int height = target.getMeasuredHeight(); 
       int negative_top = -1*(tlv_coords[1]-target_coords[1]); 
       Log.d("TOUCH VIEW DEMO", " negative_top:"+negative_top + " e.getY():"+e.getY() + " heigh:"+height); 
       Log.d("TOUCH VIEW DEMO", "Target Coords:"+ target_coords[0] +","+ target_coords[1]); 
       Log.d("TOUCH VIEW DEMO", "Tlv Coords:"+ tlv_coords[0] +","+ tlv_coords[1]); 
       if(e.getY() > negative_top && e.getY() < negative_top + height){ 
        target_name_display.setText(item.toString()); 
        adapter.remove(item); 
       } 
       //adapter.remove(item); 
       //adapter.insert(item, to); 
     } 
    }; 

    private TouchListView.RemoveListener onRemove=new TouchListView.RemoveListener() { 
     @Override 
     public void remove(int which) { 
       adapter.remove(adapter.getItem(which)); 
     } 
    }; 

    class IconicAdapter extends ArrayAdapter<String> { 
     IconicAdapter() { 
      super(TouchListViewDemo.this, R.layout.row2, array); 
     } 

     public View getView(int position, View convertView, 
               ViewGroup parent) { 
      View row=convertView; 

      if (row==null) {              
       LayoutInflater inflater=getLayoutInflater(); 

       row=inflater.inflate(R.layout.row2, parent, false); 
      } 

      TextView label=(TextView)row.findViewById(R.id.label); 

      label.setText(array.get(position)); 

      return(row); 
     } 
    } 
} 

コードには、毎回計算されるコメントとバラバラが多数含まれています。これをリファクタリングします。しかし、TouchListViewのデモを変更して、自分でこの作業を行うことができます。

私が使ったmain.xmlのレイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 
    <RelativeLayout 
     android:id="@+id/drag_here_layout" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="15dp" 
     android:layout_marginRight="15dp" 
     android:layout_weight="1.0" 
     android:background="@drawable/matches_current_match_bg" 
     android:paddingBottom="30dp" > 

     <TextView 
      android:id="@+id/drag_here_text"    
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_marginBottom="5dp" 
      android:layout_marginTop="15dp" 
      android:text="DRAG HERE" 
      android:textSize="14dp" /> 

     <ImageView 
      android:id="@+id/drag_target_area" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_below="@id/drag_here_text" 
      android:layout_marginBottom="15dp" 
      android:layout_marginLeft="15dp" 
      android:layout_marginRight="15dp" 
      android:background="#00000000" 
      android:scaleType="fitXY" 
      android:src="@drawable/match_drag_here_target" /> 
     <TextView 
      android:id="@+id/name_text"    
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_centerHorizontal="true" 
      android:layout_alignTop="@id/drag_target_area" 
      android:layout_marginBottom="5dp" 
      android:layout_marginTop="15dp" 
      android:text="" 
      android:textSize="14dp" /> 
    </RelativeLayout> 
<com.commonsware.cwac.tlv.TouchListView 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tlv="http://schemas.android.com/apk/res/com.commonsware.cwac.tlv.demo" 

    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:drawSelectorOnTop="false" 
    tlv:normal_height="64dip" 
    tlv:grabber="@+id/icon" 
    tlv:remove_mode="slideRight" 
    android:layout_weight="1.0" 
/> 
</LinearLayout> 

あなたの優れたTouchListView WidgetのためにCommonsWareに感謝します。

+0

これをデモに別のアクティビティで追加し、そのテクニックを文書化することにします。ありがとう! – CommonsWare

+0

実際には、 'TouchListView'を修正してこの作業を行い、' MotionEvent'の第3パラメータを 'DropListener'インターフェースに追加したようです。私はまだこれを追加するかもしれませんが、私は後方互換性を壊さないようにこれを行うにはどうすればよいか考える必要があります。私は誰もがそれを実装するために強制することなく、インターフェイスに新しいメソッドを追加することはできません... – CommonsWare

+0

はい私はしました。おそらくオプションの引数でインタフェースを実装する方法がありますか?または、既存のリスナー内で呼び出すことのできる別のメソッドを公開して、MotionEventを取得することもできます。また、githubにバージョン0.4.1として記載しています。1.0リリース前にインタフェースの変更があっても安全だと思います。 –

関連する問題