首先看下效果图,
主要功能分为3大块
一是滑动查看,通过viewpage来实现,方法见 http://www.cnblogs.com/lovemo1314/p/6109312.html
二、点击放大
三、下方的缩略图,横向的listview来完成
点击放大用第三方控件PhotoViewAttacher,支持手指缩放,核心代码
ImageView iv = new ImageView(this);
Bitmap bitmap = WebchatAdapter.bitmaps.get(i);
iv.setImageBitmap(bitmap); //放大及监听
iv.setScaleType(ImageView.ScaleType.MATRIX);
// 这句代码之前必须要现有默认图片来撑开位置
iv.setOnClickListener(this);
new PhotoViewAttacher(iv); //NOSON
缩略图采用横向listview, 关于这个控件的资料网上许多地方都有介绍,比如 http://rensanning.iteye.com/blog/2201789
这个控件使用起来很简单,只是把它当作纵向kistview来看就行,需要注意的是,listitem的图片布局必须指定固定的宽高,不然会出现一屏只出现一个缩略图的情况。
首先看横向listview的适配器
public class ThumbnailHorizontalLvAdapter extends MyBaseAdapter<FlagBitmap> {
private Context mContext;
private LayoutInflater mInflater;
private int pre_position; public ThumbnailHorizontalLvAdapter(Context context) {
super();
mContext = context;
mInflater = LayoutInflater.from(context);
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listitem_thumbnail_horizontal, null);
}
ImageView thumbnailImgView = ViewHolder.getView(convertView, R.id.iv_thumbnail_img);
LinearLayout container = ViewHolder.getView(convertView, R.id.ll_item_container); FlagBitmap srcBmp = getItem(position); thumbnailImgView.setScaleType(ImageView.ScaleType.FIT_CENTER);
thumbnailImgView.setImageBitmap(srcBmp.getBitmap()); if (srcBmp.isSelected()){
thumbnailImgView.setSelected(true);
setViewHeightAndWidth(thumbnailImgView, UnitUtil.dp2Px(mContext,40),UnitUtil.dp2Px(mContext,40));
setPadding(container,UnitUtil.dp2Px(mContext,6), UnitUtil.dp2Px(mContext,6));
}else {
thumbnailImgView.setSelected(false);
setViewHeightAndWidth(thumbnailImgView, UnitUtil.dp2Px(mContext,30),UnitUtil.dp2Px(mContext,30));
setPadding(container,UnitUtil.dp2Px(mContext,3), UnitUtil.dp2Px(mContext,11));
}
return convertView;
} public void setSelectImg(int pos) {
if (pos != pre_position){
getItem(pos).setSelected(true);
getItem(pre_position).setSelected(false);
pre_position = pos;
notifyDataSetChanged();
}
} public void initSelectImgPosition(int pos){
pre_position = pos;
}
private void setViewHeightAndWidth(View v, float w, float h){
ViewGroup.LayoutParams lp = v.getLayoutParams();
lp.width = (int) w;
lp.height = (int) h;
v.setLayoutParams(lp);
} private void setPadding(View v, float left, float top){
v.setPadding((int)left,(int)top,(int)left,(int)top);
} private Bitmap getPropThumnail(Bitmap bm) {
// Bitmap bb = BitmapUtil.getRoundedCornerBitmap(b, 100);
// int w = mContext.getResources().getDimensionPixelOffset(R.dimen.thumnail_default_width);
// int h = mContext.getResources().getDimensionPixelSize(R.dimen.thumnail_default_height); // Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(b, (int) UnitUtil.dp2Px(mContext, 100),
// (int) UnitUtil.dp2Px(mContext, 100)); // 获得图片的宽高
int width = bm.getWidth();
int height = bm.getHeight();
// 设置想要的大小
int newWidth = 100;
int newHeight = 100;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
float scale = scaleHeight > scaleWidth ? scaleHeight : scaleWidth;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
// 得到新的图片
Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
Bitmap thumBitmap = ThumbnailUtils.extractThumbnail(newbm, (int) UnitUtil.dp2Px(mContext, 100),
(int) UnitUtil.dp2Px(mContext, 100)); return newbm;
} }
MyBaseAdapter.java是我封装的一个适配器的基本模板,在这就不贴出来占空间了,很显然,在上面的代码中我们只重写了getview方法,这才是我们关注的重点,是不是完全与普通的list一样。由于在选中大图后,缩略图要随动更新显示,被选中的图要放大一点,带绿色边框。我这里的思路是通过selector器来实现带绿包边框的效果,而放大的效果则只需把对应的item的imageview宽高设置成比未选中的图片稍大一点,让图片来适配控件。
先来看看listitem的布局,很简单,一个固定宽高的imageview
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_item_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"> <ImageView
android:id="@+id/iv_thumbnail_img"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="2dp"
android:background="@drawable/sel_thumbnail_img"
android:src="@drawable/ico_customer_service" />
</LinearLayout>
再来看看图片的背景选择器文件
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/draw_thumbnail_sel_bg" android:state_selected="true" />
<item android:drawable="@drawable/draw_thumbnail_unsel_bg" android:state_selected="false" /> </selector>
选中状态的draw_thumbnail_sel_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2015. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
~ Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
~ Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
~ Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
~ Vestibulum commodo. Ut rhoncus gravida arcu.
--> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 连框颜色值 -->
<item>
<shape>
<solid android:color="@color/bar_tint"/>
<corners android:radius="5dp"/>
<size android:width="40dp" android:height="40dp"></size>
</shape>
</item>
<!-- 主体背景颜色值 -->
<item
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp">
<!--边框里面背景颜色 白色-->
<shape>
<corners android:radius="5dp"/>
<solid android:color="@android:color/white"/>
</shape>
</item>
</layer-list>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 连框颜色值 -->
<item>
<shape>
<solid android:color="@color/line_back"/>
<corners android:radius="5dp"/>
<size android:width="30dp" android:height="30dp"></size>
</shape>
</item>
<!-- 主体背景颜色值 -->
<item
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp">
<!--边框里面背景颜色 白色-->
<shape>
<corners android:radius="5dp"/>
<solid android:color="@android:color/white"/>
</shape>
</item>
</layer-list>
最后只要把横向listview与viewpage中的大图关联起来就好了。
//缩略图
thumbnailHorizontalLvAdapter = new ThumbnailHorizontalLvAdapter(this);
horizontalListView.setAdapter(thumbnailHorizontalLvAdapter);
horizontalListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
viewPager.setCurrentItem(position); //缩略图点击后同时刷新大图位置
thumbnailHorizontalLvAdapter.setSelectImg(position);
}
});
再看大图的适配器
public class KnowcognoViewImagePagerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
private static final String TAG = "state-viewpage-know";
private Context context;
private ViewPager viewPager;
private List<ImageView> views; private ThumbnailHorizontalLvAdapter thumbnailImgAdapter; public KnowcognoViewImagePagerAdapter(Context context, List<ImageView> viewpages, ViewPager viewPager, ThumbnailHorizontalLvAdapter thumbnailHorizontalLvAdapter) {
this.context = context;
this.viewPager = viewPager;
thumbnailImgAdapter = thumbnailHorizontalLvAdapter; this.viewPager.addOnPageChangeListener(this);
views = viewpages;
} @Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = (ImageView) views.get(position);
container.addView(imageView);
return imageView;
} @Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
} @Override
public int getCount() {
return views.size();
} @Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
} @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
} @Override
public void onPageSelected(final int position) {
} @Override
public void onPageScrollStateChanged(int state) {
System.err.println("-------state------>" + state);
switch (state) {
//在滚动完成之后
case ViewPager.SCROLL_STATE_IDLE:
System.err.println("-------state-vitem----->" + viewPager.getCurrentItem());
thumbnailImgAdapter.setSelectImg(viewPager.getCurrentItem()); //滑动完,更新缩略图位置
break;
}
}
}
最后看横向listview的控件,这个也可以去网上找
/*
* HorizontalListView.java v1.5
*
*
* The MIT License
* Copyright (c) 2011 Paul Soucy (paul@dev-smart.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/ import java.util.LinkedList;
import java.util.Queue; import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.Scroller;
public class HorizontalListView extends AdapterView<ListAdapter> { protected ListAdapter mAdapter;
private int mLeftViewIndex = -1;
private int mRightViewIndex = 0;
protected int mCurrentX;
protected int mNextX;
private int mMaxX = Integer.MAX_VALUE;
private int mDisplayOffset = 0;
protected Scroller mScroller;
private GestureDetector mGesture;
private Queue<View> mRemovedViewQueue = new LinkedList<View>();
private OnItemSelectedListener mOnItemSelected;
private OnItemClickListener mOnItemClicked;
private OnItemLongClickListener mOnItemLongClicked;
private boolean mDataChanged = false; private OnGestureMoveLinster mOnGestureMoveLinster;
private LongClickMonitor mLongClickMonitor; public HorizontalListView(Context context) {
super(context);
initView();
}
public HorizontalListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public HorizontalListView(Context context, AttributeSet attrs, int styleid ) {
super(context, attrs, styleid);
initView();
} private synchronized void initView() {
mLeftViewIndex = -1;
mRightViewIndex = 0;
mDisplayOffset = 0;
mCurrentX = 0;
mNextX = 0;
mMaxX = Integer.MAX_VALUE;
mScroller = new Scroller(getContext());
mGesture = new GestureDetector(getContext(), mOnGesture);
mLongClickMonitor = new LongClickMonitor();
} @Override
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
mOnItemSelected = listener;
} @Override
public void setOnItemClickListener(OnItemClickListener listener){
mOnItemClicked = listener;
} @Override
public void setOnItemLongClickListener(OnItemLongClickListener listener) {
mOnItemLongClicked = listener;
} private DataSetObserver mDataObserver = new DataSetObserver() { @Override
public void onChanged() {
synchronized(HorizontalListView.this){
mDataChanged = true;
}
invalidate();
requestLayout();
} @Override
public void onInvalidated() {
reset();
invalidate();
requestLayout();
}
}; @Override
public ListAdapter getAdapter() {
return mAdapter;
} @Override
public View getSelectedView() {
//TODO: implement
return null;
}
public void setOnGestureMoveLinster( OnGestureMoveLinster linster ){
this.mOnGestureMoveLinster = linster;
}
public void setMaxX( int max ){
mMaxX = max;
}
//一次滑动一个对象的宽度
private int bakWidth = 0;
private int scrollWidth = 0;
public void setScrollWidth( int width ){
scrollWidth = width;
} public void setNextX(int px){
synchronized(HorizontalListView.this){
mNextX = px;
}
requestLayout();
} @Override
public void setAdapter(ListAdapter adapter) {
if(mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataObserver);
}
mAdapter = adapter;
mAdapter.registerDataSetObserver(mDataObserver);
reset();
} private synchronized void reset(){
initView();
removeAllViewsInLayout();
requestLayout();
} @Override
public void setSelection(int position) {
//TODO: implement
} private void addAndMeasureChild(final View child, int viewPos) {
LayoutParams params = child.getLayoutParams();
if(params == null) {
params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
} addViewInLayout(child, viewPos, params, true);
child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
} @Override
protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom); if(mAdapter == null){
return;
} if(mDataChanged){
int oldCurrentX = mCurrentX;
initView();
removeAllViewsInLayout();
mNextX = oldCurrentX;
mDataChanged = false;
} if(mScroller.computeScrollOffset()){
int scrollx = mScroller.getCurrX();
mNextX = scrollx;
} if(mNextX <= 0){
mNextX = 0;
mScroller.forceFinished(true); }
if(mNextX >= mMaxX) {
mNextX = mMaxX;
mScroller.forceFinished(true);
} int dx = mCurrentX - mNextX; removeNonVisibleItems(dx);
fillList(dx);
positionItems(dx); mCurrentX = mNextX; if(!mScroller.isFinished()){
post(new Runnable(){
@Override
public void run() {
requestLayout();
}
});
}
} private void fillList(final int dx) {
int edge = 0;
View child = getChildAt(getChildCount()-1);
if(child != null) {
edge = child.getRight();
}
fillListRight(edge, dx); edge = 0;
child = getChildAt(0);
if(child != null) {
edge = child.getLeft();
}
fillListLeft(edge, dx); } private void fillListRight(int rightEdge, final int dx) {
while(rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) { View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, -1);
rightEdge += child.getMeasuredWidth(); if(mRightViewIndex == mAdapter.getCount()-1) {
int bakMaxX = mCurrentX + rightEdge - getWidth();
if( mMaxX == Integer.MAX_VALUE || bakMaxX > mMaxX ){
mMaxX = bakMaxX;
}
} if (mMaxX < 0) {
mMaxX = 0;
}
mRightViewIndex++;
} } private void fillListLeft(int leftEdge, final int dx) {
while(leftEdge + dx > 0 && mLeftViewIndex >= 0) {
View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this);
addAndMeasureChild(child, 0);
leftEdge -= child.getMeasuredWidth();
mLeftViewIndex--;
mDisplayOffset -= child.getMeasuredWidth();
}
} private void removeNonVisibleItems(final int dx) {
View child = getChildAt(0);
while(child != null && child.getRight() + dx <= 0) {
mDisplayOffset += child.getMeasuredWidth();
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mLeftViewIndex++;
child = getChildAt(0); } child = getChildAt(getChildCount()-1);
while(child != null && child.getLeft() + dx >= getWidth()) {
mRemovedViewQueue.offer(child);
removeViewInLayout(child);
mRightViewIndex--;
child = getChildAt(getChildCount()-1);
}
} private void positionItems(final int dx) {
if(getChildCount() > 0){
mDisplayOffset += dx;
int left = mDisplayOffset;
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
int childWidth = child.getMeasuredWidth();
child.layout(left, 0, left + childWidth, child.getMeasuredHeight());
left += childWidth + child.getPaddingRight();
}
}
} private boolean bOnLongPress = false;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if( !bOnLongPress && scrollWidth != 0 ){
comsumeTouchEvent( ev );
return true;
}else{
if( bOnLongPress && ev.getAction() == MotionEvent.ACTION_UP ){
bOnLongPress = false;
if(mOnGestureMoveLinster!=null && mOnGestureMoveLinster.moveend()){
return true;
}
}
if( bOnLongPress && !mOnGestureMoveLinster.canmove() )
return true;
boolean handled = super.dispatchTouchEvent(ev);
handled |= mGesture.onTouchEvent(ev);
return handled;
}
} /** 用于记录开始时候的坐标位置 */
private PointF startPoint = new PointF();
private long startPressTime = 0;
private boolean move_status = false;
public boolean comsumeTouchEvent(MotionEvent event) {
switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN:{
//AppLog.d(" MoveImageView onTouchEvent ACTION_DOWN ");
startPoint.set(event.getRawX(), event.getRawY());
bakWidth = 0;
move_status = false;
mLongClickMonitor.start();
startPressTime = System.currentTimeMillis();
break;
}
case MotionEvent.ACTION_MOVE:{
//AppLog.d(" MoveImageView onTouchEvent ACTION_MOVE "); float dx = event.getRawX() - startPoint.x; // 得到x轴的移动距离
float dy = event.getRawY() - startPoint.y; // 得到x轴的移动距离
//避免和双击冲突,大于10f才算是拖动
if(Math.abs(dx) < 40){
break;
}
move_status = true;
if( bakWidth == 0 || bakWidth + ((int)dx) > scrollWidth || bakWidth + ((int)dx) < -scrollWidth ){
bakWidth = (int)dx;
if( mNextX == 0 ){
int distance = scrollWidth - scrollWidth/8;
mNextX += dx>0?-distance:distance;
}else if(mNextX >=mMaxX){
int distance = scrollWidth - scrollWidth/8;
mNextX += dx>0?-distance:distance;
}else{
int distance = scrollWidth;
mNextX += dx>0?-distance:distance;
}
requestLayout();
}else{
bakWidth += (int)dx;
}
startPoint.set(event.getRawX(), event.getRawY());
}
break;
case MotionEvent.ACTION_UP: {
mLongClickMonitor.stop();
if( !move_status ){
if( System.currentTimeMillis() - startPressTime < 300 ){ //300ms
onClick();
}
}
move_status = false;
//AppLog.d(" MoveImageView onTouchEvent ACTION_UP ");
break;
}
default:
break;
}
return true;
} protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
synchronized(HorizontalListView.this){
mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0);
}
requestLayout(); return true;
} protected boolean onDown(MotionEvent e) {
mScroller.forceFinished(true);
return true;
} private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() { @Override
public boolean onDown(MotionEvent e) {
return HorizontalListView.this.onDown(e);
} @Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY);
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
if( mOnGestureMoveLinster!=null && mOnGestureMoveLinster.moveby( -distanceX, -distanceY ) ){
return true;
}
mNextX += (int)distanceX;
requestLayout();
return true;
} @Override
public boolean onSingleTapConfirmed(MotionEvent e) { for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
break;
} }
return true;
} @Override
public void onLongPress(MotionEvent e) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (isEventWithinView(e, child)) {
if (mOnItemLongClicked != null) {
bOnLongPress = true;
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
} }; private boolean isEventWithinView(MotionEvent e, View child) {
return isEventWithinView( e.getRawX(), e.getRawY(),child );
}
private boolean isEventWithinView( float x, float y, View child) { if( scrollWidth!=0 ){
if( x < scrollWidth/8 || x > scrollWidth*9/8 )
return false;
} Rect viewRect = new Rect();
int[] childPosition = new int[2];
child.getLocationOnScreen(childPosition);
int left = childPosition[0];
int right = left + child.getWidth();
int top = childPosition[1];
int bottom = top + child.getHeight();
viewRect.set(left, top, right, bottom);
return viewRect.contains( (int)x, (int)y );
} public interface OnGestureMoveLinster{
//返回true 消费事件了
boolean moveby( float dx, float dy );
boolean moveend();
boolean canmove();
} private static final int MSG_LONG = 1;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch ( msg.what ) {
case MSG_LONG:
onLongClick();
break;
}
}
}; class LongClickMonitor { private final int ST_RUN = 1;
private final int ST_STOP = 0; private int run_status = ST_STOP; public LongClickMonitor(){
} public void start(){
if( run_status==ST_RUN ) return; run_status = ST_RUN;
startRun();
} public void stop(){
if( run_status == ST_RUN ){
run_status = ST_STOP;
}
} public void startRun() {
new Thread(new Runnable() {
@Override
public void run() { while( run_status == ST_RUN ){
SystemClock.sleep(10);
if( System.currentTimeMillis() - startPressTime >= 1000 ){ //3S
handler.sendEmptyMessage( MSG_LONG );
break;
}
}
run_status = ST_STOP;
}
}).start();
}
}
private void onLongClick(){
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (isEventWithinView( startPoint.x, startPoint.y, child)) {
if (mOnItemLongClicked != null) {
bOnLongPress = true;
mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i));
}
break;
}
}
} private void onClick(){
for(int i=0;i<getChildCount();i++){
View child = getChildAt(i);
if (isEventWithinView( startPoint.x, startPoint.y, child)) {
if(mOnItemClicked != null){
mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
if(mOnItemSelected != null){
mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i ));
}
break;
}
}
} }
viewpage滑动查看图片并再有缩略图预览的更多相关文章
-
javascript 图片上传缩略图预览
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...
-
ReactNative学习-滑动查看图片第三方组件react-native-swiper
滑动查看图片第三方组件:react-native-swiper,现在的版本为:1.4.3,该版本还不支持Android. 下面介绍的是该组件的一些用法,可能总结的不完整,希望大家一起来共同完善. 官方 ...
-
JS兼容各个浏览器的本地图片上传即时预览效果
JS兼容各个浏览器的本地图片上传即时预览效果 很早以前 在工作曾经碰到这么一个需求,当时也是纠结了很久,也是google了很久,没有碰到合适的demo,今天特意研究了下这方面的的问题,所以也就做了个简 ...
-
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images, 本例子主要是使用HTML5 的File API,建立一個可存取到该file的url, 一个空的img标签,ID为img0,把 ...
-
html之file标签 --- 图片上传前预览 -- FileReader
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
-
【转】HTML5 jQuery图片上传前预览
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images,本例子主要是使用HTML5 的File API,建立一個可存取到该 file的url,一个空的img标签,ID为img0,把选 ...
-
ASP.NET MVC图片上传前预览
回老家过春节,大半个月,在家的日子里,吃好睡好,人也长了3.5Kg.没有电脑,没有网络,无需写代码,工作上相关的完全放下......开心与父母妻儿过个年,那样的生活令Insus.NET现在还在留恋.. ...
-
图片上传本地预览。兼容IE7+
基于JQUERY扩展,图片上传预览插件 目前兼容浏览器(IE 谷歌 火狐) 不支持safari 预览地址:http://www.jinbanmen.com/test/1.html js代码:/**名称 ...
-
DevExpress控件使用系列--ASPxUploadControl(图片上传及预览)
1.控件功能 列表控件展示数据.弹框控件执行编辑操作.Tab控件实现多标签编辑操官方说明 2.官方示例 2.1 ASPxImage http: ...
随机推荐
-
pandas保存excel
没有matlab那样的保存中间变量可以用jupyter创建文件然后在pycharm中打开但是字体很奇怪- -所以还是用excel的中间文件方式#测试涨停# ret = asc.getPctChange ...
-
Runner之记计帐项目的典型用户和用户场景
项目任务:编写日历选择界面和查明细界面(查看某一天的具体收支出状况) 1.背景 ①典型用户 (1)姓名:张云 (2)年龄:17~23 (3)收入:家长给的生活费与自己兼职(1500元/月) (4)代表 ...
-
【转载】COM 连接点
原文:COM 连接点 CLR 完全介绍 COM 连接点 Thottam R. Sriram 来自:http://msdn.microsoft.com/zh-cn/magazine/cc163361.a ...
-
Sharepoint 2010 根据用户权限隐藏Ribbon菜单(利用css)
本文介绍的是根据用户权限隐藏整个Ribbon菜单项. 操作环境:Windows Server 2008 r2+ SharePoint 2010 1.关于SharePoint 权限详细请参考:http ...
-
ECshop网点程序优化-自动生成类目页Keywords、Desciption Meta
ECshop支持针对每个新建的类目自定义Keywords.Description Meta信息,好处就不用说了,帮助SEO或者让浏览者了解这是什么页面,但如果有几百个类目的时候,人工去写这些类目又有点 ...
-
Django 模型和数据库 总结
模型和数据库 模型 首先我们在创建一个model的时候,这个类都是继承自 django.db.models.Model, 各种Model Field类型 AutoField,自动增长的IntegerF ...
-
shiro salt
1.1 散列算法 散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转成原始内容.散列算法常用于对密码进行散列,常用的散列算法有MD5.SHA.分享牛系列,分享牛专 ...
-
【BZOJ2212】[POI2011]Tree Rotations (线段树合并)
题解: 傻逼题 启发式合并线段树里面查$nlog^2$ 线段树合并顺便维护一下$nlogn$ 注意是叶子为n 总结点2n 代码: #include <bits/stdc++.h> usin ...
-
iOS网络监控— BMReachability
1. What's BMReachability? BMReachability是基于AFNetworking的Reachability类封装的监听网络状态变化的组件. 它在AF提供的无网络/wifi ...
-
从命令行运行Jmeter及jmeter参数说明、Html报告生成
为什么要命令行执行脚本,主要有以下三点: 1) 图形化界面消耗更多资源,CPU和内存 2) 图形化界面不支持大型的负载测试和性能测试 3) 命令行测试支持持续集成,例如放到Jenkins这样的CI工具 ...