1

我有一个 Horizo​​ntalScrollView 作为 ListView 的一项。每个 Horizo​​ntalScrollView 中都有可点击的图像。水平滚动视图也应该具有特定的滚动行为。我已经为单个 Horizo​​ntalScrollView 实现了它。但现在我需要列出这些滚动视图,并且每个视图都应该有这种行为。我正在使用 ParseQueryAdapter,因为我从 parse.com 获取信息。当我尝试在每个项目上使用特定滚动的代码时,只有最后一个项目具有此行为。而且它的效果非常糟糕。但也许这是我的错。请帮我为每个项目设置 onTouchListener。以及每个项目中每个 ImageView 的 onClickListener。这是我的代码

public class CustomParseQueryAdapter extends ParseQueryAdapter<Lighter> {
    Activity activity;
    int rankNumber;
    Bitmap bitmap;
    int currentScrollViewPosition;
    int middlePosition;

    HorizontalScrollView itemScrollView;
    RelativeLayout rankParentLayout;
    RelativeLayout lighterNameAndMilesLayout;

    GestureDetector gestureDetector;

    public CustomParseQueryAdapter(Context context){
        super(context, new QueryFactory<Lighter>() {
            @Override
            public ParseQuery<Lighter> create() {
                ParseQuery<Lighter> query = new ParseQuery<>("Lighter");
                query.orderByDescending("miles");
                query.include("master");
                return query;
            }
        });
        activity = (Activity) context;
        rankNumber = 1;
    }

    @Override
    public View getItemView(Lighter lighter, View v, ViewGroup parent) {
        if (v == null){
            v = View.inflate(getContext(), R.layout.ranking_list_item, null);
        }

        super.getItemView(lighter, v, parent);

        gestureDetector = new GestureDetector(new CustomGestureDetector());

        itemScrollView = (HorizontalScrollView) v.findViewById(R.id.item_scroll_view);



        LinearLayout itemParentLayout = (LinearLayout) v.findViewById(R.id.rank_item_linear_scroll_view);
        RelativeLayout crossedCitiesParentLayout = (RelativeLayout) v.findViewById(R.id.item_crossed_cities_layout);
        RelativeLayout timesCheckedParentLayout = (RelativeLayout) v.findViewById(R.id.item_times_checked_layout);
        rankParentLayout = (RelativeLayout) v.findViewById(R.id.item_rank_layout);
        lighterNameAndMilesLayout = (RelativeLayout) v.findViewById(R.id.item_lighter_name_and_miles_layout);

        TextView crossedCitiesAmount = (TextView) v.findViewById(R.id.item_crossed_cities);
        TextView timesCheckedAmount = (TextView) v.findViewById(R.id.item_times_checked);
        TextView itemRankNumber = (TextView) v.findViewById(R.id.item_rank_number);

        ImageView lighterImage = (ImageView) v.findViewById(R.id.item_lighter_image);
        TextView lighterName = (TextView) v.findViewById(R.id.item_lighter_name);
        TextView milesTravelled = (TextView) v.findViewById(R.id.item_lighter_miles_travelled);

// This userImage ImageView should have the onClickListener to start another fragment
        ImageView userImage = (ImageView) v.findViewById(R.id.item_user_image);

        String lighterColor = lighter.getColor();
        itemParentLayout.setBackgroundColor(FragmentMap.getColor(lighterColor, activity.getResources()));
        crossedCitiesParentLayout.setBackgroundColor(FragmentMap.getAnotherColor(lighterColor, activity.getResources()));
        timesCheckedParentLayout.setBackgroundColor(FragmentMap.getAnotherColor(lighterColor, activity.getResources()));
        rankParentLayout.setBackgroundColor(FragmentMap.getAnotherColor(lighterColor, activity.getResources()));
        lighterNameAndMilesLayout.getLayoutParams().width = FragmentMap.getScreenSize(activity).x - FragmentMap.MARGIN;

        crossedCitiesAmount.setText(lighter.getCitiesAmount() + " CITIES");
        timesCheckedAmount.setText(lighter.getTimesChecked() + " TIMES");
        itemRankNumber.setText(String.valueOf(rankNumber));
        rankNumber++;

        setUpLighterImage(lighterImage, lighterColor);
        lighterName.setText(lighter.getLighterName().toUpperCase());
        milesTravelled.setText(lighter.getIntMiles() + " MILES TRAVELLED");
        final ParseUser lighterMasterUser = lighter.getParseUser("master");
        final String userProfileID = lighterMasterUser.getString("profileID");
        Thread thread = new Thread(new Runnable() {
            public void run() {
                bitmap = FragmentMap.getBitmap(userProfileID, activity);
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        userImage.setImageBitmap(FragmentMap.getBitmapWithTineCircle(bitmap, activity));

        middlePosition = rankParentLayout.getBottom() - FragmentMap.MARGIN;

        v.post(new Runnable() {
            @Override
            public void run() {
                itemScrollView.scrollTo(middlePosition, 0);
                currentScrollViewPosition = 0;
            }
        });

        itemScrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        });

        return v;
    }

    private void setUpLighterImage(ImageView view, String color){
        switch (color){
            case "red":
                view.setImageResource(R.drawable.red);
                break;
            case "pink":
                view.setImageResource(R.drawable.pink);
                break;
            case "green":
                view.setImageResource(R.drawable.green);
                break;
            case "orange":
                view.setImageResource(R.drawable.orange);
                break;
            case "yellow":
                view.setImageResource(R.drawable.yellow);
                break;
            case "silver":
                view.setImageResource(R.drawable.silver);
                break;
            // it is gold, but was light brown
            case "gold":
                view.setImageResource(R.drawable.gold);
                break;
            case "copper":
                view.setImageResource(R.drawable.copper);
                break;
        }
    }

    class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                               float velocityY) {
            if (e1.getX() < e2.getX()) {
                getScrollPosition("left");
            } else {
                getScrollPosition("right");
            }
//            mapTitleScrollView.smoothScrollTo(scrollPosition, 0);
            return true;
        }
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                                float distanceY){
            return true;
        }
    }

    private void getScrollPosition(String direction){
        switch (direction){
            case "left":
                if (currentScrollViewPosition == 1){ // if scrollview is in rightmost position move to center
                    toCenterPosition();
                } else if (currentScrollViewPosition == 0){ // if scrollview is in center position move left
                    toLeftPosition();
                }
                break;
            case "right":
                if (currentScrollViewPosition == -1){ // if scrollview is in leftmost position move to center
                    toCenterPosition();
                } else if (currentScrollViewPosition == 0){ // if scrollview is in center position move right
                    toRightPosition();
                }
                break;
        }
    }

    private void toLeftPosition(){
        currentScrollViewPosition = -1;
        itemScrollView.fullScroll(HorizontalScrollView.FOCUS_LEFT);
    }

    private void toRightPosition(){
        currentScrollViewPosition = 1;
        itemScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
    }

    private void toCenterPosition(){
        currentScrollViewPosition = 0;
        itemScrollView.smoothScrollTo(middlePosition, 0);
    }
}

这是我的 ListView 片段代码

public class FragmentList extends ListFragment {

    ApplicationInterface fragmentHolder;

    CustomParseQueryAdapter mainAdapter;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            fragmentHolder = (ApplicationInterface) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString());
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_list, container, false);

        mainAdapter = new CustomParseQueryAdapter(getActivity());
        setListAdapter(mainAdapter);

        return view;
    }
}

和 ListView 的 XML:

<ListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

我还需要在列表视图的整个项目上使用 onClickListener。但我认为它应该在我的FragmentList课堂上实施

4

1 回答 1

1

好的,所以如果有人对我的解决方案感兴趣,那就是:我的手势检测器仅在列表视图的最后一项上工作的原因是用于存储 Horizo​​ntalScrollView 的全局变量。我将其设为本地并将其作为参数传递给我的手势检测器。我还更改了 onFling 方法检测,因为它与 onClick 侦听器有冲突。它抛出 NullPointerException,告诉我我正在尝试在空对象上使用方法 MotionEvent.getX()。这就是我的代码现在的样子:

public class CustomParseQueryAdapter extends ParseQueryAdapter<Lighter> {
    Activity activity;
    int rankNumber;
    Bitmap bitmap;
    int currentScrollViewPosition;

    ApplicationInterface fragmentHolder;

    public CustomParseQueryAdapter(Context context, ApplicationInterface fragmentHolder){
        super(context, new QueryFactory<Lighter>() {
            @Override
            public ParseQuery<Lighter> create() {
                ParseQuery<Lighter> query = new ParseQuery<>("Lighter");
                query.orderByDescending("miles");
                query.include("master");
                return query;
            }
        });
        activity = (Activity) context;
        rankNumber = 1;

        this.fragmentHolder = fragmentHolder;
    }

    @Override
    public View getItemView(final Lighter lighter, View v, ViewGroup parent) {
        if (v == null){
            v = View.inflate(getContext(), R.layout.ranking_list_item, null);
        }



        final HorizontalScrollView itemScrollView = (HorizontalScrollView) v.findViewById(R.id.item_scroll_view);
        itemScrollView.setSmoothScrollingEnabled(true);

        v.post(new Runnable() {
            @Override
            public void run() {
                itemScrollView.fullScroll(View.FOCUS_RIGHT);
                currentScrollViewPosition = 1;
            }
        });

        LinearLayout itemParentLayout = (LinearLayout) v.findViewById(R.id.rank_item_linear_scroll_view);
        RelativeLayout crossedCitiesParentLayout = (RelativeLayout) v.findViewById(R.id.item_crossed_cities_layout);
        RelativeLayout timesCheckedParentLayout = (RelativeLayout) v.findViewById(R.id.item_times_checked_layout);
        RelativeLayout rankParentLayout = (RelativeLayout) v.findViewById(R.id.item_rank_layout);
        RelativeLayout lighterNameAndMilesLayout = (RelativeLayout) v.findViewById(R.id.item_lighter_name_and_miles_layout);

        TextView crossedCitiesAmount = (TextView) v.findViewById(R.id.item_crossed_cities);
        TextView timesCheckedAmount = (TextView) v.findViewById(R.id.item_times_checked);
        TextView itemRankNumber = (TextView) v.findViewById(R.id.item_rank_number);

        ImageView lighterImage = (ImageView) v.findViewById(R.id.item_lighter_image);
        TextView lighterName = (TextView) v.findViewById(R.id.item_lighter_name);
        TextView milesTravelled = (TextView) v.findViewById(R.id.item_lighter_miles_travelled);
        ImageView userImage = (ImageView) v.findViewById(R.id.item_user_image);

        final String lighterColor = lighter.getColor();
        final String lighterObjectId = lighter.getObjectId();
        itemParentLayout.setBackgroundColor(FragmentMap.getColor(lighterColor, activity.getResources()));
        crossedCitiesParentLayout.setBackgroundColor(FragmentMap.getColor(lighterColor, activity.getResources()));
        timesCheckedParentLayout.setBackgroundColor(FragmentMap.getAnotherColor(lighterColor, activity.getResources()));
        rankParentLayout.setBackgroundColor(FragmentMap.getAnotherColor(lighterColor, activity.getResources()));
        lighterNameAndMilesLayout.getLayoutParams().width = FragmentMap.getScreenSize(activity).x - FragmentMap.MARGIN;

        crossedCitiesAmount.setText(lighter.getCitiesAmount() + " CITIES");
        timesCheckedAmount.setText(lighter.getTimesChecked() + " TIMES");
        itemRankNumber.setText("#" + String.valueOf(rankNumber));
        rankNumber++;

        setUpLighterImage(lighterImage, lighterColor);
        lighterName.setText(lighter.getLighterName().toUpperCase());
        milesTravelled.setText(lighter.getIntMiles() + " MILES TRAVELLED");
        final ParseUser lighterMasterUser = lighter.getParseUser("master");
        final String userProfileID = lighterMasterUser.getString("profileID");
        Thread thread = new Thread(new Runnable() {
            public void run() {
                bitmap = FragmentMap.getBitmap(userProfileID, activity);
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        userImage.setImageBitmap(FragmentMap.getBitmapWithTineCircle(bitmap, activity));

        final GestureDetector gestureDetector = new GestureDetector(
                new CustomGestureDetector(currentScrollViewPosition, itemScrollView));

        lighterNameAndMilesLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fragmentHolder.onMapRedirect(lighterObjectId, lighterColor);
            }
        });

        itemScrollView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gestureDetector.onTouchEvent(event);
            }
        });

        super.getItemView(lighter, v, parent);

        return v;
    }

    private void setUpLighterImage(ImageView view, String color){
        switch (color){
            case "red":
                view.setImageResource(R.drawable.red);
                break;
            case "pink":
                view.setImageResource(R.drawable.pink);
                break;
            case "green":
                view.setImageResource(R.drawable.green);
                break;
            case "orange":
                view.setImageResource(R.drawable.orange);
                break;
            case "yellow":
                view.setImageResource(R.drawable.yellow);
                break;
            case "silver":
                view.setImageResource(R.drawable.silver);
                break;
            // it is gold, but was light brown
            case "gold":
                view.setImageResource(R.drawable.gold);
                break;
            case "copper":
                view.setImageResource(R.drawable.copper);
                break;
        }
    }

    class CustomGestureDetector extends GestureDetector.SimpleOnGestureListener {
        int currentScrollViewPosition;
        HorizontalScrollView itemScrollView;

        public CustomGestureDetector(int currentPosition, HorizontalScrollView scrollView){
            currentScrollViewPosition = currentPosition;
            itemScrollView = scrollView;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                               float velocityY) {
            if (velocityX > 0){
                getScrollPosition("left");
            } else {
                getScrollPosition("right");
            }
            return true;
        }
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                                float distanceY){
            if (distanceX < 0){
                getScrollPosition("left");
            } else {
                getScrollPosition("right");
            }
            return true;
        }

        private void getScrollPosition(String direction){
            switch (direction){
                case "left":
                    if (currentScrollViewPosition == 1){
                        toLeftPosition();
                    } else if (currentScrollViewPosition == 0){
                    toLeftPosition();
                }
                    break;
                case "right":
                    if (currentScrollViewPosition == -1){
                        toRightPosition();
                    } else if (currentScrollViewPosition == 0){
                    toRightPosition();
                }
                    break;
            }
        }

        private void toLeftPosition(){
            currentScrollViewPosition = -1;
            itemScrollView.fullScroll(HorizontalScrollView.FOCUS_LEFT);
        }

        private void toRightPosition(){
            currentScrollViewPosition = 1;
            itemScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
        }
    }
}
于 2015-05-06T12:55:10.463 回答