Android-解决ViewFlipper与ScrollView滑动响应事件拦截的问题

来源:互联网 发布:淘宝网字画拍卖网 编辑:程序博客网 时间:2024/05/18 02:55
最近在做一个简单的展示界面时,遇到了一个比较棘手的问题。由于要展示多项内容,所以使用ViewFlipper作为水平滑动容器;而每项内容中由于许多文本较长,因此需要使用ScrollView作为垂直滑动容器。基本的界面布局大致如下:外部文件common_list_view.xml:<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/geyan_query_view_layout"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"android:background="@drawable/mid_bg"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_marginTop="43dip"android:orientation="vertical"android:gravity="top"android:layout_gravity="top"><Galleryandroid:id="@+id/gallery_data"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="top"android:layout_gravity="top"android:spacing="60dip"android:paddingLeft="6dip"android:paddingRight="6dip"></Gallery></LinearLayout><ImageViewandroid:id="@+id/main_background"android:layout_width="fill_parent"android:layout_height="fill_parent"/><include layout="@layout/common_title_view"android:id="@+id/title"/></RelativeLayout>内部文件common_info_view.xml:<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"android:id="@+id/linear"><TextViewandroid:id="@+id/text_title"android:layout_width="fill_parent"android:layout_height="wrap_content"android:padding="5dip"android:layout_marginTop="5dip"android:gravity="center"android:textSize="20sp"android:textStyle="bold"android:textColor="#181712"/><ScrollViewandroid:id="@+id/scroll"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_marginBottom="5dip"android:fadeScrollbars="true"><TextViewandroid:id="@+id/text_detail"android:layout_width="fill_parent"android:layout_height="wrap_content"android:lineSpacingMultiplier="1.3"android:textSize="18sp"android:textColor="#181712"android:singleLine="false"/></ScrollView></LinearLayout>由于ViewFlipper在外,ScrollView在内,因此一般的做法是定义一个手势响应类来处理响应事件,并将响应事件的处理交给内层的ScrollView。大致代码如下:import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.GestureDetector;import android.view.GestureDetector.SimpleOnGestureListener;import android.view.LayoutInflater;import android.view.Menu;import android.view.MotionEvent;import android.view.View;import android.view.Window;import android.widget.TextView;import android.widget.Toast;import android.widget.ViewFlipper; public class Test1 extends Activity { private ViewFlipper viewFlipper; private String[] descriptionsArray;private String[] titleArray; private int selectedPosition; private TextView textViewTitle;private TextView textViewContent;private FriendlyScrollView scroll; private LayoutInflater mInflater; private GestureDetector gestureDetector; @Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stub requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.common_info_list_view); InitUI(); super.onCreate(savedInstanceState); Toast.makeText(this, R.string.hello, Toast.LENGTH_SHORT).show();} @Overridepublic boolean onCreateOptionsMenu(Menu menu) {// TODO Auto-generated method stub        super.onCreateOptionsMenu(menu);        return false;} @Overridepublic void onBackPressed() {// TODO Auto-generated method stubfinish();} private void InitUI(){ viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper_data); mInflater = LayoutInflater.from(this); fillDate(); viewFlipper.addView(getContentView());} private void fillDate(){selectedPosition = 0; titleArray = getResources().getStringArray(R.array.title_array);descriptionsArray = getResources().getStringArray(R.array.description_array); gestureDetector = new GestureDetector(new CommonGestureListener());} private View getContentView() {View contentView = new View(this);contentView = mInflater.inflate(R.layout.common_info_item_view, null); textViewTitle = (TextView) contentView.findViewById(R.id.text_title);textViewContent = (TextView) contentView.findViewById(R.id.text_detail); textViewTitle.setText(titleArray[selectedPosition]);textViewTitle.setPadding(10, 0, 10, 0);textViewContent.setText(descriptionsArray[selectedPosition]);textViewContent.setPadding(10, 5, 10, 5); scroll = (FriendlyScrollView) contentView.findViewById(R.id.scroll);scroll.setOnTouchListener(onTouchListener);scroll.setGestureDetector(gestureDetector); return contentView;} private View.OnTouchListener onTouchListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubreturn gestureDetector.onTouchEvent(event);}}; public class CommonGestureListener extends SimpleOnGestureListener { @Overridepublic boolean onDown(MotionEvent e) {// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onDown...");return false;} @Overridepublic void onShowPress(MotionEvent e) {// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onShowPress...");super.onShowPress(e);} @Override    public void onLongPress(MotionEvent e) {        // TODO Auto-generated method stubLog.d("QueryViewFlipper", "----> Jieqi: do onLongPress...");    } @Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onSingleTapConfirmed...");return false;} @Overridepublic boolean onSingleTapUp(MotionEvent e) {// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onSingleTapUp...");return false;} @Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY){// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onFling...");if (e1.getX() - e2.getX() > 100 && Math.abs(velocityX) > 50) {//向左selectedPosition = selectedPosition + 1 < titleArray.length ? (selectedPosition + 1) : 0;viewFlipper.addView(getContentView());viewFlipper.setInAnimation(AnimationControl.inFromRightAnimation());                viewFlipper.setOutAnimation(AnimationControl.outToLeftAnimation());                viewFlipper.showNext();                viewFlipper.removeViewAt(0);} else if (e2.getX() - e1.getX() > 100 && Math.abs(velocityX) > 50) {//向右selectedPosition = selectedPosition > 0 ? (selectedPosition - 1) : (titleArray.length - 1);viewFlipper.addView(getContentView());viewFlipper.setInAnimation(AnimationControl.inFromLeftAnimation());                viewFlipper.setOutAnimation(AnimationControl.outToRightAnimation());viewFlipper.showNext();viewFlipper.removeViewAt(0);}return true;} @Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY) {// TODO Auto-generated method stubLog.d("QueryViewFlipper", "====> Jieqi: do onScroll...");return super.onScroll(e1, e2, distanceX, distanceY);}     }}这个时候问题出现了,通过Log显示,当ScrollView中内容太短的时候,ScrollView不会触发OnScroll和OnFling事件,导致ViewFlipper左右滑动不响应。(当然后来的另一个测试表明这个问题在ListView上不存在)为了解决这一个问题,我重新自定义了一个FriendlyScrollView类,来重写ScrollView的onTouchEvent和dispatchTouchEvent方法,具体如下:import android.content.Context;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.widget.ScrollView; public class FriendlyScrollView extends ScrollView { GestureDetector gestureDetector;     public FriendlyScrollView(Context context) {super(context);// TODO Auto-generated constructor stub} public FriendlyScrollView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub} public FriendlyScrollView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub} public void setGestureDetector(GestureDetector gestureDetector) {this.gestureDetector = gestureDetector;} @Overridepublic boolean onTouchEvent(MotionEvent event) {    super.onTouchEvent(event);    return gestureDetector.onTouchEvent(event);} @Overridepublic boolean dispatchTouchEvent(MotionEvent ev){    gestureDetector.onTouchEvent(ev);    super.dispatchTouchEvent(ev);    return true;}  }然后将common_info_view.xml和程序中的ScrollView改成FriendlyScrollView,终于解决了这个问题。原文链接:http://blog.liaoxiaoqi.com/?p=484Tags:   AndroidAndroid-ScrollViewAndroid-tutorAndroid-ViewFlipper


原创粉丝点击