Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
173 views
in Technique[技术] by (71.8m points)

android - Gallery like view with center image zoom

Here I need a gallery like view with only three images to be shown at a time on screen. In this the middle image will be larger than the two other images on its sides.

If the user scrolls the view next images will slide on screen as it does in gallery and at a time only three images will be shown out of which the center image should automatically zoom when it is shown on screen and remaining two should be smaller than it.

Here I can't use gallery because it is depreciated in android.

I was able to make a gallery like view with help of viewpager using code on this link. It shows only three images on screen at a time, which fits my one requirement. But i am not able to get the central image that is visible on screen and zoom it. Although I was able to get the clicked image on screen.

Can someone please tell me where do I need to modify this code and what I need to add in it to get the image that is in center from the images shown on screen and zoom it.

I know that there is no center image on screen according to viewpager and it is just showing three images on screen at a time because of modifications in code.

I have also tried:-

  • GridView with horizontal scroll
  • HorizontalScrollView with horizontal linear layout

but viewpager seems to be a better solution, because it stops the scrolling with only three items on screen because of viewpager's inherent properties.

Thanks in advance for any help.

and If someone knows any other method to achieve it, please tell me and I'll try it.

P.S. For anyone who wants the full code, I have added it as an answer, which has zoom capability also. Just few additions in accepted answer. :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Following code will help you to make a gallery like view which will have center lock. It responds to touch and swipe both. It shows three images on the screen at a time and the center image is zoomed.

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class CenteringHorizontalScrollView extends HorizontalScrollView implements View.OnTouchListener {

private Context mContext;

private static final int SWIPE_PAGE_ON_FACTOR = 10;

private int mActiveItem;

private float mPrevScrollX;

private boolean mStart;

private int mItemWidth;

View targetLeft, targetRight;
ImageView leftImage, rightImage;

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

    mContext=context;
    mItemWidth = 100; // or whatever your item width is.
    setOnTouchListener(this);
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    int x = (int) event.getRawX();

    boolean handled = false;
    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            if (mStart) {
                mPrevScrollX = x;
                mStart = false;
            }

            break;
        case MotionEvent.ACTION_UP:
            mStart = true;
            int minFactor = mItemWidth / SWIPE_PAGE_ON_FACTOR;

            if ((mPrevScrollX - (float) x) > minFactor) {
                if (mActiveItem < getMaxItemCount() - 1) {
                    mActiveItem = mActiveItem + 1;
                }
            }
            else if (((float) x - mPrevScrollX) > minFactor) {
                if (mActiveItem > 0) {
                    mActiveItem = mActiveItem - 1;
                }
            }

            scrollToActiveItem();

            handled = true;
            break;
    }

    return handled;
}

private int getMaxItemCount() {
    return ((LinearLayout) getChildAt(0)).getChildCount();
}

private LinearLayout getLinearLayout() {
    return (LinearLayout) getChildAt(0);
}

/**
 * Centers the current view the best it can.
 */
public void centerCurrentItem() {
    if (getMaxItemCount() == 0) {
        return;
    }

    int currentX = getScrollX();
    View targetChild;
    int currentChild = -1;

    do {
        currentChild++;
        targetChild = getLinearLayout().getChildAt(currentChild);
    } while (currentChild < getMaxItemCount() && targetChild.getLeft() < currentX);

    if (mActiveItem != currentChild) {
        mActiveItem = currentChild;
        scrollToActiveItem();
    }
}

/**
 * Scrolls the list view to the currently active child.
 */
private void scrollToActiveItem() {
    int maxItemCount = getMaxItemCount();
    if (maxItemCount == 0) {
        return;
    }

    int targetItem = Math.min(maxItemCount - 1, mActiveItem);
    targetItem = Math.max(0, targetItem);

    mActiveItem = targetItem;

    // Scroll so that the target child is centered
    View targetView = getLinearLayout().getChildAt(targetItem);

    ImageView centerImage = (ImageView)targetView;
    int height=300;//set size of centered image
    LinearLayout.LayoutParams flparams = new LinearLayout.LayoutParams(height, height);
    centerImage.setLayoutParams(flparams);

    //get the image to left of the centered image
    if((targetItem-1)>=0){
        targetLeft = getLinearLayout().getChildAt(targetItem-1);
        leftImage = (ImageView)targetLeft;
        int width=250;//set the size of left image
        LinearLayout.LayoutParams leftParams = new LinearLayout.LayoutParams(width,width);
        leftParams.setMargins(0, 30, 0, 0);
        leftImage.setLayoutParams(leftParams);
    }

    //get the image to right of the centered image
    if((targetItem+1)<maxItemCount){
        targetRight = getLinearLayout().getChildAt(targetItem+1);
        rightImage = (ImageView)targetRight;
        int width=250;//set the size of right image
        LinearLayout.LayoutParams rightParams = new LinearLayout.LayoutParams(width,width);
        rightParams.setMargins(0, 30, 0, 0);
        rightImage.setLayoutParams(rightParams);
    }

    int targetLeft = targetView.getLeft();
    int childWidth = targetView.getRight() - targetLeft;

    int width = getWidth() - getPaddingLeft() - getPaddingRight();
    int targetScroll = targetLeft - ((width - childWidth) / 2);

    super.smoothScrollTo(targetScroll, 0);
}

/**
 * Sets the current item and centers it.
 * @param currentItem The new current item.
 */
public void setCurrentItemAndCenter(int currentItem) {
    mActiveItem = currentItem;
    scrollToActiveItem();
}

}

In your xml add the horizontal scroll view like follow:-

<com.yourpackagename.CenteringHorizontalScrollView
                android:id="@+id/HSVImage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/Horizontalalternative"
                >

                <LinearLayout
                    android:id="@+id/linearImage"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="horizontal" >
                </LinearLayout>
            </com.yourpackagename.CenteringHorizontalScrollView>

Define a Linear layout in your activity.

LinearLayout imageGallery;

Then get it as follows:-

imageGallery=(LinearLayout)findViewById(R.id.linearImage);

Now you have to add imageView to your LinearLayout. Here I assume that you have images in your drawable folder and you have made an array of ids of your images that you want to add to gallery. So you can do it via following method in your activity:-

for(int i=0; i<lengthOfImageIdArray; i++){
    ImageView image=new ImageView(YourActivityName.this);
    image.setBackgroundResource(yourArrayName[i]);
    imageGallery.addView(image);
}

You can also set the width of images dynamically, so that they fit every screen, with only little extra effort. If anyone needs help with that, please tell me, although i suggest that you should try it yourself.

Happy coding ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...