在这里,我需要一个像视图的图库,一次只能在屏幕上显示三个图像。在这里,中间的图像将比其两侧的其他两个图像大。
如果用户滚动视图,则下一个图像将在屏幕上滑动,并且一次只显示三个图像,中心图像在屏幕上显示时应自动缩放,其余两个应该是小于它。
这里我不能使用gallery,因为它在android中被折旧了。
我可以使用this link上的代码在viewpager的帮助下创建一个类似于视图的图库。它一次只显示屏幕上的三个图像,符合我的一个要求。但我无法获得屏幕上可见的中央图像并进行缩放。虽然我能够在屏幕上显示点击的图像。
有人可以告诉我在哪里需要修改this代码以及我需要在其中添加的内容,以便从屏幕上显示的图像中获取中心的图像并进行缩放。
我知道根据viewpager屏幕上没有中心图像,由于代码修改,它一次只能在屏幕上显示三个图像。
我也尝试过: -
但是viewpager似乎是一个更好的解决方案,因为它会因为viewpager的固有属性而停止在屏幕上只有三个项目的滚动。
提前感谢您的帮助。
并且如果有人知道任何其他方法来实现它,请告诉我,我会尝试。
P.S。对于想要完整代码的人,我已将其添加为答案,它也具有缩放功能。 在接受的答案中添加了几个。:)
答案 0 :(得分:14)
以下代码将帮助您制作一个类似于视图的图库,它将具有中心锁定功能。它响应触摸和滑动两者。它一次在屏幕上显示三个图像,并且中心图像被缩放。
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();
}
}
在你的xml中添加水平滚动视图,如下所示: -
<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>
在活动中定义线性布局。
LinearLayout imageGallery;
然后按如下方式获取: -
imageGallery=(LinearLayout)findViewById(R.id.linearImage);
现在您必须将imageView添加到LinearLayout。在这里,我假设您在可绘制文件夹中有图像,并且您已经创建了一系列要添加到图库的图像ID。所以你可以通过以下方法在你的活动中做到: -
for(int i=0; i<lengthOfImageIdArray; i++){
ImageView image=new ImageView(YourActivityName.this);
image.setBackgroundResource(yourArrayName[i]);
imageGallery.addView(image);
}
您还可以动态设置图像的宽度,以便它们适合每个屏幕,只需要很少的额外工作。如果有人需要帮助,请告诉我,虽然我建议你自己尝试一下。
快乐的编码;)
答案 1 :(得分:12)
在ViewPager中覆盖setPrimaryItem并使中心项更大。
将HorizontalScrollView与LinearLayout一起使用会出现什么问题?如果它居中,你可以做类似的事情(假设你已经
/**
* A centering HSV loosely based on http://iotasol.blogspot.com/2011/08/creating-custom-horizontal-scroll-view.html
*/
public class CenteringHorizontalScrollView extends HorizontalScrollView implements View.OnTouchListener {
private static final int SWIPE_PAGE_ON_FACTOR = 10;
private int mActiveItem;
private float mPrevScrollX;
private boolean mStart;
private int mItemWidth;
public CenteringHorizontalScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
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);
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();
}
}