2013-04-20 1 views
0

센터 잠금 장치가있는 HorizontalScrollview에서 작업 중입니다. 이 유래 스레드에서 발견 된 일부 코드를 기반으로합니다D-Pad 용 onScrollChange 및 사용자 정의 HorizontalScrollView 용 터치

HorizontalScrollView with imageviews as a child and while scrolling the center of the image in the screen should play animation?

문제는 제대로 D 패드 탐색을 지원하지 않은 것입니다. 다음 항목으로 이동하지 않고 점프 위치로 이동합니다. D-Pad 탐색 기능을 올바르게 사용하도록 코드를 수정했지만 터치 스크롤이 작동하지 않게 만들었습니다. 또한 TextView가 올바르게 추가 되었더라도 클릭 리스너가 제거 된 것처럼 보이는 이유가 있습니다. 어쨌든, 주된 문제는 onScrollChange 이벤트에 대한 코드에 다시 추가하면 Touch에서는 올바르게 작동하지만 D-Pad 탐색은 화면을 벗어난 상태에서 다시 화면으로 가져온 경우 항목을 건너 뛸 수 있다는 것입니다.

는 다음 사용 xml.layout이다 : 나는 문제가 onScrollChange 방법 주위에 알고

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/mainLayout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/serenity_bonsai_logo" 
    android:orientation="vertical" 
    tools:context=".MainActivity" > 

    <LinearLayout 
     android:id="@+id/main_menu_row1" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:orientation="horizontal" > 

     <DigitalClock 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="#50000000" 
      android:textColor="#F0F0F0" 
      android:textSize="20sp" /> 
    </LinearLayout> 

    <us.nineworlds.serenity.widgets.CenterLockHorizontalScrollview 
     android:id="@+id/mainGalleryMenu" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:background="#50000000" 
     android:layout_centerInParent="true" 
     android:clickable="true" 
     android:scrollbars="none" > 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="150dp" 
      android:layout_gravity="center_vertical" 
      android:background="@android:color/transparent" 
      android:orientation="horizontal" 
      android:clickable="true" > 
     </LinearLayout> 
    </us.nineworlds.serenity.widgets.CenterLockHorizontalScrollview> 

</RelativeLayout> 

그리고 그것은 새로운 센터보기를해야한다 무엇을 계산하지만, D를 얻을하는 방법을 잘하는 방법 - 터치 패드를 터치하고 멋지게 함께 스크롤합니다. 다음은 CenterLockHorizontalScrollView 클래스의 관련 코드입니다.

public class CenterLockHorizontalScrollview extends HorizontalScrollView { 
private ListAdapter mAdapter; 

private int mCenterViewPosition = -1; 
private MenuDataSetObserver menuDataObserver; 
private OnItemSelectedListener selectedItemListener; 
private boolean keypadScrollEvent = false; 

public CenterLockHorizontalScrollview(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    this.setHorizontalFadingEdgeEnabled(true); 
    this.setHorizontalScrollBarEnabled(false); 
    this.setFadingEdgeLength(5); 
    this.setSmoothScrollingEnabled(true); 
} 

@Override 
protected void onLayout(boolean changed, int l, int t, int r, int b) { 

    super.onLayout(changed, l, t, r, b); 

    if (getChildCount() == 0) { 
     return; 
    } 

    initCenterView(); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    if (getChildCount() == 0) 
     return; 

    ViewGroup parent = (ViewGroup) getChildAt(0); 

    if (parent.getChildCount() == 0) 
     return; 

    View FirstChild = parent.getChildAt(0); 

    int LeftPadding = (getWidth()/2) 
      - (FirstChild.getMeasuredWidth()/2); 

    View LastChild = parent.getChildAt(getChildCount() - 1); 

    int RightPadding = (getWidth()/2) 
      - (LastChild.getMeasuredWidth()/2); 

    if (parent.getPaddingLeft() != LeftPadding 
      && parent.getPaddingRight() != RightPadding) { 
     parent.setPadding(LeftPadding, parent.getPaddingTop(), 
       RightPadding, parent.getPaddingBottom()); 
     requestLayout(); 
    } 
} 

/* (non-Javadoc) 
* @see android.view.View#onKeyDown(int, android.view.KeyEvent) 
*/ 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    int totalItems = 0; 
    if (mAdapter.getCount() > 0) { 
     totalItems = mAdapter.getCount(); 
    } 

    int currentPosition = mCenterViewPosition; 

    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { 
     if (currentPosition > 0) { 
      setSelectedIndex(currentPosition - 1); 
     } else { 
      setSelectedIndex(totalItems - 1); 
     } 
     keypadScrollEvent = true; 
     scrollToSelectedIndex(); 
     keypadScrollEvent = false; 
     return true; 
    } 

    if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { 
     if (currentPosition < totalItems - 1) { 
      setSelectedIndex(currentPosition + 1); 
     } else { 
      setSelectedIndex(0); 
     } 
     keypadScrollEvent = true; 
     scrollToSelectedIndex(); 
     keypadScrollEvent = false; 
     return true; 
    } 

    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || 
     keyCode == KeyEvent.KEYCODE_ENTER) { 
     ViewGroup parent = (ViewGroup) getChildAt(0); 
     View view = parent.getChildAt(mCenterViewPosition); 
     view.setOnClickListener(new GalleryOnClickListener(view.getContext())); 
     view.performClick(); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 


private int getCenterPositionFromView() { 

    int scrollingCenterView = getScrollingCenterView(); 
    if (mCenterViewPosition != scrollingCenterView) { 
     ViewGroup parent = (ViewGroup) getChildAt(0); 
     View view = parent.getChildAt(scrollingCenterView); 
     selectedItemListener.onItemSelected(view, scrollingCenterView, scrollingCenterView); 
     mCenterViewPosition = scrollingCenterView; 
    } 

    return scrollingCenterView; 
} 


private int getScrollingCenterView() { 
    if(getChildCount() == 0) 
      return -1; 

     int centerView= 0; 
     int centerX = getScrollX() + (getWidth()/2); 

     ViewGroup parent = (ViewGroup) getChildAt(0); 

     if(parent.getChildCount() == 0) 
      return -1; 

     View child = parent.getChildAt(0); 

     while(child != null && child.getRight() <= centerX && centerView < parent.getChildCount()) 
     { 
      centerView++; 
      child = parent.getChildAt(centerView); 
     } 

     if(centerView >= parent.getChildCount()) { 
      centerView = parent.getChildCount() - 1; 
     } 

     return centerView;  

} 


public int getCenterViewPosition() { 
    return mCenterViewPosition; 
} 

public ListAdapter getAdapter() { 
    return mAdapter; 
} 

public void setAdapter(ListAdapter mAdapter) { 

    this.mAdapter = mAdapter; 
    if (menuDataObserver != null) { 
     mAdapter.unregisterDataSetObserver(menuDataObserver); 
    } 
    mAdapter.registerDataSetObserver(new MenuDataSetObserver()); 
} 

private void fillViewWithAdapter() { 
    if (getChildCount() == 0 || mAdapter == null) 
     return; 

    ViewGroup parent = (ViewGroup) getChildAt(0); 

    parent.removeAllViews(); 

    for (int i = 0; i < mAdapter.getCount(); i++) { 
     parent.addView(mAdapter.getView(i, null, parent)); 
    } 
    setSelectedIndex(0); 
} 



@Override 
protected void onScrollChanged(int l, int t, int oldl, int oldt) { 
    super.onScrollChanged(l, t, oldl, oldt); 

    if (keypadScrollEvent == false) { 
     getCenterPositionFromView(); 
    } 
    initCenterView(); 
} 

private void initCenterView() { 
    Log.i(getClass().getName(), "initCenterView"); 

    if (getChildCount() == 0) 
     return; 

    ViewGroup parent = (ViewGroup) getChildAt(0); 

    if (parent.getChildCount() == 0) 
     return; 

    int centerView = getCenterViewPosition(); 

    if (centerView == -1) { 
     mCenterViewPosition = 0; 
     centerView = 0; 
    } 

    if (centerView != -1 && centerView != mCenterViewPosition 
      && parent.getChildAt(0).getLeft() >= 0) { 
     scrollToSelectedIndex(); 
    } 

    if (centerView < 0 || centerView > parent.getChildCount()) 
     return; 

    for (int i = 0; i <= parent.getChildCount(); i++) { 

     if (! (parent.getChildAt(i) instanceof TextView)) { 
      continue; 
     } 

     if (i == centerView) { 
      // Start Animation 
      //setSelectedIndex(i); 
      //scrollToSelectedIndex(); 
      return; 
     } else { 
      // Remove Animation for other Views 
     } 
    } 

} 

public int getSelectedIndex() { 
    return getCenterViewPosition(); 
} 

public void setSelectedIndex(int index) { 
    Log.i(getClass().getName(), "setSelectedIndex"); 

    if (getChildCount() == 0) 
     return; 

    ViewGroup parent = (ViewGroup) getChildAt(0); 

    if (index < 0 || index > parent.getChildCount()) { 
     throw new ArrayIndexOutOfBoundsException(index); 
    } 

    mCenterViewPosition = index; 

    //onSelectedItemChanged.onSelectedChanged(this, mCenterViewPosition); 
    selectedItemListener.onItemSelected(parent.getChildAt(index), index, 0); 

    requestLayout(); 
} 

protected void scrollToSelectedIndex() { 

    ViewGroup parent = (ViewGroup) getChildAt(0); 

    View child = parent.getChildAt(mCenterViewPosition); 

    if (child == null) { 
     return; 
    } 

    int offsetX = ((child.getLeft() + child.getRight())/2) - (this.getWidth()/2); 

    smoothScrollTo(offsetX, 0); 
} 

public class MenuDataSetObserver extends DataSetObserver { 

    @Override 
    public void onChanged() { 
     fillViewWithAdapter(); 
    } 

} 

public OnItemSelectedListener getOnItemSelectedListener() { 
    return selectedItemListener; 
} 

public void setOnItemSelectedListener(OnItemSelectedListener selectedItemListener) { 
    this.selectedItemListener = selectedItemListener; 
} 
} 

onScrollChange의 중앙 확인은 제외하고 D 패드 탐색은 올바르게 작동하지만 터치 스크롤은 올바르게 작동하지 않습니다.

답변

0

내 권장 사항은 onKeyDown 이벤트를 재정의하지 않고 대신 onClickListener를 첨부하는 것입니다. ViewPager 너비를 무시하고 대신에 ViewPager를 사용하여 내부에있는 항목을 고려한 적이 있습니까?

+0

아직 ViewPager를 확인하지 않았습니다. 주로 갤러리보기에서 사라지려고하는데, 수정 된 가로 스크롤은 좋은 후보자처럼 보입니다. 그렇지 않으면 D-Pad 키가 예상대로 응답하지 않아서 (즉, 프레스 당 2 ~ 3 개 항목 건너 뛰기) onKeyDown 이벤트를 무시해야했습니다. – kingargyle

+0

데이터 세트가 작 으면 수평 스크롤이 제대로 작동합니다. 큰 데이터 세트 (또는 무한한 데이터 세트)가 있다면 ViewPager를보고 너비를 무시하는 것이 좋습니다. – Krispy