2011-08-19 17 views
0

イメージの水平スライディンググリッドを作成しようとしています。表示する画像ビューを含むTableLayoutsを提供するアダプタを備えたギャラリービューを使用しています。すべてがうまく見えますが、画面に触れると(MotionEvent.ACTION_DOWN)、ギャラリーが突然左右に動いてスワイプするのが難しくなります(現在表示されている子が前面に表示されます)。どのようにそれを修正するための任意の手掛かり?これが最善のアプローチですか?ギャラリー内の大きなビューの問題

編集:ここでは、ソースコード

import java.util.LinkedList; 
import java.util.WeakHashMap; 
import android.content.Context; 
import android.graphics.Color; 
import android.util.AttributeSet; 
import android.view.GestureDetector; 
import android.view.Gravity; 
import android.view.KeyEvent; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Adapter; 
import android.widget.AdapterView; 
import android.widget.BaseAdapter; 
import android.widget.Gallery; 
import android.widget.GridView; 
import android.widget.ImageView; 
import android.widget.SpinnerAdapter; 
import android.widget.TableLayout; 
import android.widget.TableRow; 
public class Dock extends Gallery { 
private Adapter mAdapter; 
private int numLines=1; 
private int numColumns=1; 
protected int columnWidth = GridView.AUTO_FIT; 
private OnItemClickListener myOnItemClickListener; 
private OnItemLongClickListener myOnItemLongClickListener; 
private OnItemSelectedListener myOnItemSelectedClickListener; 
private GestureDetector interceptGest = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener(){ 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     return true; 
    }; 
}); 
public int columnSpacing = 10; 
private CustomAdapter adapt; 
public Dock(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    initDock(); 
} 
public Dock(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initDock(); 
} 
public Dock(Context context) { 
    super(context); 
    initDock(); 
} 
private void initDock(){ 
    this.setSpacing(50); 
    this.setHorizontalFadingEdgeEnabled(false); 
    this.setGravity(Gravity.CENTER); 
    this.setBackgroundColor(Color.GREEN); 
    this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
} 
public int getNumLines() { 
    return numLines; 
} 
public void setNumLines(int numLines) { 
    this.numLines = numLines; 
} 
public int getNumColumns() { 
    return numColumns; 
} 
public void setNumColumns(int numColumns) { 
    this.numColumns = numColumns; 
} 
public void setOnItemClickListener(
     android.widget.AdapterView.OnItemClickListener listener) { 
    this.myOnItemClickListener = listener; 
} 

public void setOnItemLongClickListener(
     android.widget.AdapterView.OnItemLongClickListener listener) { 
    this.myOnItemLongClickListener = listener; 
} 
public void setOnItemSelectedListener(
     android.widget.AdapterView.OnItemSelectedListener listener) { 
    this.myOnItemSelectedClickListener = listener; 
} 
public void setAdapter(final SpinnerAdapter adapter) { 
    adapt = new CustomAdapter(adapter); 
    mAdapter = adapter; 
    super.setAdapter(adapt); 
} 

@Override 
public SpinnerAdapter getAdapter() { 
    return (SpinnerAdapter) mAdapter; 
} 
private class CustomGrid extends TableLayout{ 
    private AdapterView<Adapter> mAdapterView = new AdapterView<Adapter>(getContext()){ 
     @Override 
     public Adapter getAdapter() { 
      return mAdapter; 
     } 
     @Override 
     public View getSelectedView() { 
      return Dock.this.findFocus(); 
     } 
     @Override 
     public void setAdapter(Adapter adapter) { 
      Dock.this.setAdapter((SpinnerAdapter) adapter); 
     } 
     @Override 
     public void setSelection(int position) { 
      Dock.this.setSelection(position); 
     } 
    }; 
    private int page; 
    private Adapter adapter; 
    protected android.widget.AdapterView.OnItemClickListener mOnItemClickListener; 
    protected android.widget.AdapterView.OnItemLongClickListener mOnItemLongClickListener; 
    protected android.widget.AdapterView.OnItemSelectedListener mOnItemSelectedListener; 
    public CustomGrid(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     initGrid(); 
    } 
    public CustomGrid(Context context) { 
     super(context); 
     initGrid(); 
    } 
    private void initGrid(){ 
     this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); 
     this.setFocusable(false); 
    } 
    public void setPage(int position) { 
     this.page = position; 
    } 
    public void setAdapter(BaseAdapter adapter) { 
     this.adapter = adapter; 
    } 
    public void setOnItemClickListener(
      android.widget.AdapterView.OnItemClickListener onItemClickListener) { 
     this.mOnItemClickListener = onItemClickListener; 
    } 
    public void setOnItemLongClickListener(
      android.widget.AdapterView.OnItemLongClickListener onItemLongClickListener) { 
     this.mOnItemLongClickListener = onItemLongClickListener; 
    } 
    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     boolean ret = false; 
     if(ev.getAction()==MotionEvent.ACTION_MOVE) 
      ret = true; 
     else 
      ret = super.onInterceptTouchEvent(ev); 
     return ret; 
    } 
    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     if(ev.getAction()==MotionEvent.ACTION_MOVE) 
      return false; 
     else 
      return super.onTouchEvent(ev); 
    } 
    public void setOnItemSelectedListener(
      android.widget.AdapterView.OnItemSelectedListener onItemSelectedListener) { 
     this.mOnItemSelectedListener = onItemSelectedListener; 
    } 
    private View getCachedView(int position, ViewGroup parent) { 
     int p = position + page*getNumColumns()*getNumLines(); 
     if(p<adapter.getCount()) 
      return adapter.getView(p, null, parent); 
     else 
      return null; 
    } 
    private void refreshGrid(){ 
     if(mAdapter==null) 
      return; 
     int count=0; 
     if(numLines>1) 
      this.setPadding(5, 0, 5, 0); 
     TableRow line = null; 
     View view = null; 
     for(int i = 0; i<numLines; i++){ 
      line = new TableRow(getContext()); 
      line.setBaselineAligned(false); 
      line.setGravity(Gravity.CENTER); 
      line.setFocusable(false); 
      for(int j = 0; j< numColumns; j++){ 
       this.setColumnShrinkable(j, true); 
       this.setColumnStretchable(j, true); 
       view = getCachedView(count, line); 
       if(view!=null){ 
        final int position = count + page*getNumColumns()*getNumLines(); 
        view.setOnClickListener(new OnClickListener() { 
         @Override 
         public void onClick(View arg0) { 
          if(mOnItemClickListener!=null) 
           mOnItemClickListener.onItemClick(mAdapterView, arg0, position, mAdapter.getItemId(position)); 
         } 
        }); 
        view.setOnLongClickListener(new OnLongClickListener() { 
         @Override 
         public boolean onLongClick(View arg0) { 
          if(mOnItemLongClickListener!=null) 
           return mOnItemLongClickListener.onItemLongClick(mAdapterView, arg0, position, mAdapter.getItemId(position)); 
          else return false; 
         } 
        }); 
        view.setOnFocusChangeListener(new OnFocusChangeListener() { 
         @Override 
         public void onFocusChange(View arg0, boolean arg1) { 
          if(mOnItemSelectedListener!=null&&arg1){ 
           mOnItemSelectedListener.onItemSelected(mAdapterView, arg0, position, mAdapter.getItemId(position)); 
          } 
         } 
        }); 
        view.setFocusable(false); 
        line.addView(view); 
       } 
       count++; 
      } 
      if(numLines>1) 
       while(line.getChildCount()<numColumns){ 
        View v = this.getEmptyView(); 
        v.setFocusable(false); 
        line.addView(v); 
       } 
      this.addView(line); 
     } 
    } 
    private View getEmptyView() { 
     ImageView ret = new ImageView(getContext()); 
     ret.setBackgroundColor(Color.TRANSPARENT); 
     return ret; 
    } 
} 
private class CustomAdapter extends BaseAdapter{ 
    private WeakHashMap<Integer,CustomGrid> cache = new WeakHashMap<Integer,CustomGrid>(); 
    private LinkedList<Integer> cacheId = new LinkedList<Integer>(); 
    private Adapter adapter; 
    public CustomAdapter(Adapter a){ 
     super(); 
     adapter = a; 
    } 
    public long getItemId(int position) { 
     return position; 
    } 
    public Object getItem(int position) { 
     return null; 
    } 
    public int getCount() { 
     int n = adapter.getCount()/(numColumns*numLines); 
     if(adapter.getCount()%(numColumns*numLines)!=0) 
      n++; 
     return n; 
    } 
    private CustomGrid getPage(final int position){ 
     CustomGrid ret = new CustomGrid(getContext()); 
     ret.setPage(position); 
     ret.setAdapter((BaseAdapter) adapter); 
     ret.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView<?> adapterV, View v, 
        int pos, long id) { 
       //int page = position; 
       if(myOnItemClickListener!=null){ 
        myOnItemClickListener.onItemClick(adapterV, v, pos, adapter.getItemId(pos)); 
       } 
      } 
     }); 
     ret.setOnItemLongClickListener(new OnItemLongClickListener() { 
      public boolean onItemLongClick(AdapterView<?> adapterV, 
        View arg1, int pos, long arg3) { 
       //int page = position; 
       if(myOnItemLongClickListener!=null){ 
        return myOnItemLongClickListener.onItemLongClick(adapterV, arg1, pos, adapter.getItemId(pos)); 
       } 
       else 
        return false; 
      } 
     }); 
     ret.setOnItemSelectedListener(new OnItemSelectedListener() { 
      public void onItemSelected(AdapterView<?> adapterV, 
        View arg1, int pos, long arg3) { 
       if(myOnItemSelectedClickListener!=null){ 
        myOnItemSelectedClickListener.onItemSelected(adapterV, arg1, pos, adapter.getItemId(pos)); 
       } 
      } 
      public void onNothingSelected(AdapterView<?> arg0) { 
       if(myOnItemSelectedClickListener!=null) 
        myOnItemSelectedClickListener.onNothingSelected(arg0); 
      } 
     }); 
     ret.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
     ret.setGravity(Gravity.CENTER); 
     ret.setBackgroundColor(Color.BLUE); 
     ret.refreshGrid(); 
     return ret; 
    } 
    public View getView(int position, View convertView, ViewGroup parent) { 
     convertView = cache.get(position); 
     if(convertView==null){ 
      convertView = getPage(position); 
      while(cache.size()>3){ 
       cache.remove(cacheId.removeFirst()); 
      } 
      cache.put(position, (CustomGrid) convertView); 
      cacheId.add(position); 
      if(position<getCount()){ 
       cache.put(position+1, getPage(position+1)); 
       cacheId.add(position+1); 
      } 
     } 
     return convertView; 
    } 
    public void flush() { 
     cache.clear(); 
     cacheId.clear(); 
    } 
}; 
public void setColumnWidth(int width) { 
    this.columnWidth = width; 
} 
public void setColumnMargin(int margin){ 
    this.columnSpacing = margin; 
} 
private MotionEvent primTouch; 
@Override 
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
     float velocityY) { 
    if(e1!=null&&e2!=null){ 
     float dist = e1.getX()-e2.getX(); 
     if(Math.abs(dist)>30){ 
      if(dist>0) 
       return onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT)); 
      else 
       return onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT)); 
     } 
    } 
    return true; 
} 
private MotionEvent interm; 
private boolean scrollingHorizontally=false; 


public void flush(){ 
    adapt.flush(); 
} 
@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    if(ev.getAction()==MotionEvent.ACTION_DOWN) 
     primTouch = ev; 
    if(ev.getAction()==MotionEvent.ACTION_MOVE) 
     return true; 
    else 
     return scrollingHorizontally; 
} 
@Override 
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
    scrollingHorizontally = true; 
    return super.onScroll(e1, e2, distanceX, distanceY); 
} 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
    switch(event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     primTouch=event; 
     return super.onTouchEvent(event); 
    case MotionEvent.ACTION_MOVE: 
     scrollingHorizontally=true; 
     break; 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_CANCEL: 
     scrollingHorizontally = false; 
     if(primTouch!=null){ 
      float dist = primTouch.getX()-event.getX(); 
      if(Math.abs(dist)>30){ 
       if(dist>0) 
        return onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT)); 
       else 
        return onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT)); 
      } 
     } 
     break; 
    } 
    return super.onTouchEvent(event); 
} 
} 

EDIT 2:私は、関数onInterceptTouchEvent(MotionEventのEV)のすべてのタッチイベントを処理した場合ことを考え出した(私は常にtrueを返すように設定した場合)、問題は消滅しますが、子に設定されているonClickListenerは無効になります。 onItemClickListenerを使用した場合、または一度検出されたクリックをディスパッチする子構造を正確に把握している場合は問題ありません。

+0

参照用にコードを追加する必要があります。 – user370305

答えて

0

ギャラリーにはセッティング中にハードになる中央ロック機構があります。これを試すことができますLINK

私はこれを実際に見てきました。あなたがしていることにかなり合っています。

+0

それは動作していないようです。それは、ビューを引き伸ばし、どんなイベントにも反応しない。 –

+0

'はイベントに反応しませんでした。私はその部分がトリッキーだったと思います。しかし、私はそれを動作させるために管理しました。 – Samuel

+0

確かにトリッキーですが、今はxDでも動作します。私はこのビューのカスタムバージョンを使用しています。ありがとうございました:D –

関連する問題