- 浏览: 3533 次
最新评论
<div class="iteye-blog-content-contain" style="font-size: 14px">
由于涉及到工作内容保密的问题,所以无法提供源码,只能提供涉及该项功能的实现,本着开源和互相学习以及以后相同功能的重复利用的目的。
GridView虽然也支持横向滚动,但是并不支持代码控制,所以还是用到一个横向滚动来代替这个功能
每个gridview的Item布局
绘制背景图片
绘制雷达区域的座位表和选择区域,实现点击事件,同步实际ScrollView和GridView的同步
Fragment或者Activity中局部代码
从雷达区域来的消息处理,同步实际GridView的滚动
给自己mark一下
</div>
由于涉及到工作内容保密的问题,所以无法提供源码,只能提供涉及该项功能的实现,本着开源和互相学习以及以后相同功能的重复利用的目的。
GridView虽然也支持横向滚动,但是并不支持代码控制,所以还是用到一个横向滚动来代替这个功能
<HorizontalScrollView android:id="@+id/hs_gridview" android:layout_width="610dp" android:layout_height="750dp" android:layout_weight="1" android:fillViewport="true" android:scrollbars="horizontal" > <LinearLayout android:layout_width="610dp" android:layout_height="490dp" > <cn.com.bcl.infoissuingsys.common.CommonGridView android:id="@+id/gridView" android:layout_width="1200dp" android:layout_height="490dp" android:layout_margin="0dp" android:horizontalSpacing="20dp" android:listSelector="@android:color/transparent" android:numColumns="20" android:scrollbarStyle="outsideInset" android:scrollbarThumbVertical="@drawable/scrollbar_vertical_thumb" android:scrollbarTrackVertical="@drawable/scrollbar_vertical_track" android:scrollbars="vertical" android:stretchMode="columnWidth" android:verticalSpacing="5dp" /> </LinearLayout> </HorizontalScrollView>
每个gridview的Item布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <cn.com.bcl.infoissuingsys.common.CommonImageView android:id="@+id/zuoweiimage" android:layout_width="40dp" android:layout_height="35dp" android:scaleType="fitXY" android:src="@drawable/keyixuan"/> <cn.com.bcl.infoissuingsys.common.CommonTextView android:id="@+id/zuoweihao" android:layout_width="40dp" android:layout_height="35dp" android:textColor="#000000" android:textSize="15dp" android:text="01" android:gravity="center"/> </RelativeLayout>
绘制背景图片
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.view.SurfaceHolder; import android.view.SurfaceHolder.Callback; import android.view.SurfaceView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.LinearLayout.LayoutParams; public class RadarBgView extends SurfaceView implements SurfaceHolder.Callback { private String TAG = "RadarView"; private SurfaceHolder mHolder; private Context mCnxt; private int mSeatWidth = 410; private int mSeatHeight = 220; private int mStartSeatTop = 40; private int mLine = 0; private int mColumn=0; private int mLineNoWidth = 20; public RadarBgView(Context context) { super(context); } public RadarBgView(Context context,int line,int column) { super(context); this.mLine = line; this.mColumn = column; mCnxt = context; mHolder=this.getHolder(); mHolder.addCallback(this); setZOrderOnTop(true); mHolder.setFormat(PixelFormat.TRANSLUCENT); setFocusable(false); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { drawBg(mLine,mColumn); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } /** change background */ public void notifyBgChange(){ } /**draw background by seat */ public void drawBg(int line,int column){ Paint paint=new Paint(); // paint.setColor(Color.BLACK); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); int divider = 1; /** onriginal 图片 */ Bitmap originalSeatBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.small); int originalWidth = originalSeatBitmap.getWidth(); int originalHeight = originalSeatBitmap.getHeight(); /** 新的高度和宽度 */ float newWidth = (mSeatWidth-mLineNoWidth-divider*(column-1))/column; float newHeight = (mSeatHeight-divider*(line-1))/line; /** 计算缩放比例 */ float scaleWidth = newWidth/originalWidth; float scaleHeight = newHeight/originalHeight; /**取得要缩放的参数 */ Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); /** 生成新图片 */ Bitmap newBm = Bitmap.createBitmap(originalSeatBitmap, 0, 0, originalWidth, originalHeight,matrix,true); originalSeatBitmap.recycle(); originalSeatBitmap = null; Paint testP=new Paint(); // paint.setColor(Color.BLACK); testP.setAntiAlias(true); testP.setTextSize(5); Canvas canvas = null; try { canvas = mHolder.lockCanvas(); synchronized (mHolder) { int offsetY = mStartSeatTop; for (int i = 0; i < line; i++) { canvas.drawText(String.valueOf(i+1), 6, offsetY+newBm.getHeight(), testP); int offsetX = mLineNoWidth; for (int j = 0; j < column; j++) { canvas.drawBitmap(newBm, offsetX, offsetY, paint); offsetX+=(newBm.getWidth()+divider); } offsetX=0; offsetY+=(newBm.getHeight()+divider); } } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) { mHolder.unlockCanvasAndPost(canvas); } } } }
绘制雷达区域的座位表和选择区域,实现点击事件,同步实际ScrollView和GridView的同步
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class RadarAreaView extends SurfaceView implements SurfaceHolder.Callback { private String TAG = "RadarAreaView"; private SurfaceHolder mHolder; private Handler mHandler; /** gridView 的 显示区域宽高 */ private int mDisplayWidth = 630; private int mDisplayHeight = 490; /** gridView real 高宽 */ private int mWholeWidth; private int mWholeHeight; /** 雷达座位区域长宽 */ private int mRadarSeatWidth = 410; private int mRadarSeatHeight = 260; /** 显示区域偏移量 */ private int mOffsetX = 0; private int mOffsetY = 40; /** 座位行列数 */ private int mLineNum = 0; private int mColumnNum = 0; /** radar和gridView的长高缩放比例 */ private float mScaleX; private float mScaleY; private int mLineNoWidth = 20; private int mStartSeatTop = 40; Bitmap mAreaBm = null; public RadarAreaView(Context context) { super(context); } public RadarAreaView(Context context, int line, int column,Handler handler) { super(context); mHolder = this.getHolder(); mHolder.addCallback(this); setZOrderOnTop(true); mHolder.setFormat(PixelFormat.TRANSLUCENT); this.mLineNum = line; this.mColumnNum = column; this.mHandler = handler; setFocusable(false); /** 初始化可视区域的图片大小 */ initAreaBm(); /** 雷达View与实际 View 的长宽比例 */ mScaleX = ((float)(mRadarSeatWidth-mLineNoWidth))/mWholeWidth; mScaleY = ((float)(mRadarSeatHeight-mStartSeatTop)/mWholeHeight); } /** * 根据实际比例初始化选择区域框的的图片大小 */ private void initAreaBm() { Bitmap originalBm = BitmapFactory.decodeResource(getResources(), R.drawable.area); int originalWidth = originalBm.getWidth(); int originalHeight = originalBm.getHeight(); int dividerX = 20; int dividerY = 5; /** original 图片 */ mWholeWidth = 40 * mColumnNum + dividerX * (mColumnNum - 1); mWholeHeight = 35 * mLineNum + dividerY * (mLineNum - 1); /** 计算缩放比例 */ float scaleWidth = ((float)mDisplayWidth) / mWholeWidth; float scaleHeight = ((float)mDisplayHeight) / mWholeHeight; /** 计算Area宽缩放后的长宽 */ float newAreaWidth = (mRadarSeatWidth-mLineNoWidth)*scaleWidth; float newAreaHeight = (mRadarSeatHeight-mStartSeatTop)*scaleHeight; /** 计算缩放比例 */ float newScaleWidth = newAreaWidth/originalWidth; float newScaleHeight = newAreaHeight/originalHeight; /**取得要缩放的参数 */ Matrix matrix = new Matrix(); matrix.postScale(newScaleWidth, newScaleHeight); /** 生成新图片 */ mAreaBm = Bitmap.createBitmap(originalBm, 0, 0, originalWidth, originalHeight, matrix, true); originalBm.recycle(); originalBm = null; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { drawArea(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { } /** clear && refresh Area by offsetX & offset Y */ public void drawArea() { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); paint.setDither(true); Paint clearP = new Paint(); clearP.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); Canvas canvas = null; try { canvas = mHolder.lockCanvas(); synchronized (mHolder) { canvas.drawPaint(clearP); canvas.drawBitmap(mAreaBm, mOffsetX, mOffsetY, null); } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) { mHolder.unlockCanvasAndPost(canvas); } } } /** 点击雷达区域时,同步GridView显示的位置 */ @Override public boolean onTouchEvent(MotionEvent event) { final float x = event.getX(); final float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: /**caculate scroll */ /**雷达区域每个item的宽高 */ float xItemSize = (mRadarSeatWidth-mLineNoWidth)/mColumnNum; float yItemSize = (mRadarSeatHeight-mStartSeatTop)/mLineNum; int cornerX = 0; int cornerY = 0; /** 图像是左上角开始画的,所以为了让方框居于点击位置的中心,进行了偏移计算 */ cornerX=(int) (x-mAreaBm.getWidth()/2); cornerY=(int) (y-mAreaBm.getHeight()/2); int offsetX = 0; int offsetY = 0; /** 对于超出座位图的点击事件进行处理 */ if (cornerX<=mLineNoWidth) { offsetX = 0; } else if(cornerX>=(mRadarSeatWidth-mAreaBm.getWidth())){ offsetX = (int) ((mRadarSeatWidth-mLineNoWidth-mAreaBm.getWidth())); }else{ offsetX = (int) ((cornerX-mLineNoWidth)); } if (cornerY<=mStartSeatTop) { offsetY = 0; } else if(cornerY>=(mRadarSeatHeight-mAreaBm.getHeight())){ offsetY = (int) ((mRadarSeatHeight-mStartSeatTop-mAreaBm.getHeight())); }else{ offsetY = (int) ((cornerY-mStartSeatTop)); } int scrollX = (int) (offsetX/mScaleX); int position =(int) ((int)(offsetY/yItemSize)*mColumnNum+(int)(offsetX/xItemSize)); /** scroll seat gridView */ /** 从View发消息给Activity同步实际View的滚动 */ Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putInt("scrollX", scrollX); bundle.putInt("position", position); bundle.putInt("linePosition", (int)(offsetY/yItemSize)); msg.setData(bundle); mHandler.sendMessage(msg); /**caculate and draw Area */ /** 根据点击位置和计算的左上角位置重绘选择区域 */ if (cornerX<=mLineNoWidth) { mOffsetX = mLineNoWidth; } else if(cornerX>=(mRadarSeatWidth-mAreaBm.getWidth())){ mOffsetX = (int) ((mRadarSeatWidth-mAreaBm.getWidth())); }else{ mOffsetX =(int) cornerX; } if (cornerY<=mStartSeatTop) { mOffsetY = mStartSeatTop; } else if(cornerY>=(mRadarSeatHeight-mAreaBm.getHeight())){ mOffsetY = (int) ((mRadarSeatHeight-mAreaBm.getHeight())); }else{ mOffsetY = (int) cornerY; } drawArea(); break; default: break; } return true; } /**GridView滚动时传入当前第一个可见的position 控制雷达的垂直方向的滚动同步 */ public void scrollVertical(int position){ float yItemSize = (mRadarSeatHeight-mStartSeatTop)/mLineNum; mOffsetY= (int) ((position/mColumnNum) * yItemSize)+mStartSeatTop; drawArea(); } /** 通过传入的HorizantalScrollView的move offset来控制雷达的水平方向的滚动同步 */ public void scrollHorizontal(int originalX){ mOffsetX =mLineNoWidth + (int)(originalX*mScaleX); drawArea(); } }
Fragment或者Activity中局部代码
/** * GridView */ private GridView mGridView; /** * HorizontalScrollView */ private HorizontalScrollView mHsGridView; private RelativeLayout mRelativeLayout_radar; private RadarAreaView mRav; private RadarBgView mRbv;
mRbv = new RadarBgView(mContext,mNumLine,mNumColumns); mRav = new RadarAreaView(mContext,mNumLine,mNumColumns,radarHandler); mRelativeLayout_radar.addView(mRbv); mRelativeLayout_radar.addView(mRav); /** 控制垂直滚动 */ mGridView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(final AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { View v = view.getChildAt(view.getFirstVisiblePosition()/mNumColumns); int[] location = new int[2]; if(null!=v){ v.getLocationOnScreen(location); if (mIsInitDefault) { mDefaultLocation = location[1]; mIsInitDefault = false; } mRav.scrollVertical(view.getFirstVisiblePosition()); } } }); /** HorizontalScrollView控制横向滚动同步 */ mHsGridView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: int offsetX = mHsGridView.getScrollX(); mRav.scrollHorizontal(offsetX); break; default: break; } return false; } });
从雷达区域来的消息处理,同步实际GridView的滚动
private Handler radarHandler = new Handler(){ public void handleMessage(Message msg) { Bundle bundle = msg.getData(); final int position = bundle.getInt("position"); final int linePosition = bundle.getInt("linePosition"); final int scrollX = bundle.getInt("scrollX"); mGridView.post(new Runnable() { @Override public void run() { mHsGridView.scrollTo(scrollX, (int) mGridView.getY()); mGridView.setSelection(position); } }); }; };
给自己mark一下
</div>
相关推荐
TRW还研发了主动/可逆安全带技术,能够在碰撞时更有效地帮助管理乘员的身体动能,并且可以通过最新技术帮助乘员找到并扣好安全带、在车辆高速运动中拉紧织带、降低乘员偏离座位的风险。 德尔福作为另一家领先的...
首先,我们从上海大剧院的案例出发,理解了如何通过有序数对的方式来表示座位的位置。有序数对(排数,座数)是一个简单而有效的工具,用来描述二维平面上的精确位置。 对于确定位置,我们发现通常需要两个数据,即...
在教室中,确定一个座位通常需要两个数据,即排数和座数,例如"第2排第3座"。而在电影院,同样的原则适用,如"12排8座"。如果只有排数而没有座数,我们无法准确找到位置,因为同一排可能有多个座位。 课件引入了一...
95第二排车辆优先座位 96智能部署自动驾驶汽车的安全机制 97面向车辆的乘客显示 98基于音频样本的警笛检测方法 99用于雷达的相位编码线性频率调制 100模拟虚拟对象 ………… 资料太多不一一列举了,共169份 报告...
最后,雷达探测器和建筑区的例子展示了在实际应用中,位置可以用角度和距离来描述。例如,目标C、F的位置使用了角度和距离,而目标A、B、D、E的位置表示同样需要遵循这样的规则。 综上所述,《确定位置》这一章涵盖...
- 雷达站与小岛的位置描述中,A、B、C岛的位置需要给出相对于雷达站的方向和距离,例如A岛的位置可能是北偏东某一角度,距离雷达站某一千米。 4. **坐标与路径规划**: - 图形中的路线规划问题,如乐乐的移动路径...
8. **雷达目标**:雷达探测目标的位置通常使用极坐标表示,如C(6,120°)和F(5,210°)。而表示不正确的是D,因为角度应该是顺时针或逆时针从正北开始计算。 9. **正整数排列**:在特定的数列排列中,有序数对可以...
26. 空中预警引导(AWACS, Airborne Warning and Control System):装备有先进雷达系统的军用飞机,用于空中监视和指挥。 27. 客用飞机(airliner, passenger aircraft):专门设计用于搭载乘客的飞机。 28. 远程...
雷达 YDAR是一种电影院预订系统,使用OOP风格PHP和MYSQL(仍在仪表板和电影院管理员上工作)。 查看已部署的网站,请 特征 登录注册 将类别添加到您的帐户或将其删除。 选择电影院。 从“电影”页面中选择要观看的...
压力传感器则检测座椅上的重量变化,从而确定座位是否被占用。 在硬件设计上,这些传感器会与微控制器(MCU)相连,MCU负责处理传感器数据,进行信号处理和算法运算。MCU的选择通常需要考虑其处理能力、功耗和接口...
14/03/2021 修复了从ASE页面打开FCR页面的问题雷达最大检测范围从10K更改为8K 禁止火箭齐射以防止错误的是用海德拉斯(Hyas)射击的地狱火// TEMP // 添加了香草热传感器CFG红外传感器固定翼Cscope图标的尺寸增加...
4. **安全装置**:配备有气象雷达、空中防撞系统、近地警告系统、遇险定位装置、浮筒、火警探测和灭火系统,确保飞行安全。 5. **客舱设施**:客舱内有照明、通风、加温和冷气系统,以及与驾驶舱通话装置。两侧有6...
首先,通过一个学生座位表的例子,我们看到小刚的位置被标记为(5,2),这意味着他在第5列,第2行。这种坐标系统是基于笛卡尔坐标系,其中第一个数字代表列号,第二个数字代表行号,通常列号写在前面,行号写在后面...
5. 车内环境理解:除了乘员存在和位置,系统还需要理解车内环境的整体情况,包括座位布局、物体位置等,以便在必要时进行干预,如开启空调、调整座椅或警告乘客注意安全。 6. 数据隐私与安全:收集和处理乘客数据的...
例如,座位可以被描述为"第几排第几个座位"。这种确定位置的方法称为直角坐标系统,类似于平面直角坐标系中的x轴和y轴。 2. 在航海中,确定位置需要三个数据,分别是经度、纬度和深度。经度用来指示东西方向的位置...
1. 座位编号系统可以类比为坐标系统,如张艳的座位记为(2,4),意味着她在第2排第4列,王刚的位置为(5,8),则他在第5排第8列。 2. 点的坐标描述了它离坐标轴的距离:点A(3,-4)到y轴的距离是3,到x轴的距离...
- 座位情况可以用有序数对来表示,例如第一排第一列可以表示为(1, 1),以此类推,对于图7-1-1-2中的学生座位,可以根据位置用有序数对表示。 5. 象棋中的位置表示: - "相"走一步不能跨越其他棋子,所以其位置...
1. 多媒体教室用于理论教学,确保有足够的座位和教学资源。 2. 陈设室用于展示各种救生设备,如救生衣、防水保温服和气胀式救生筏。 3. 设有50米×25米游泳池,配备5米跳台,用于个人求生技能训练。 4. 模拟消防舱室...
另外,以后还会增加用于车辆与车辆和车辆与基础设施间通信的DSRC(专用短程通信,5.9GHz),也可能还有防碰撞雷达,不过这通常是一个单独系统。 用于所有这些设备的大多数电子电路都位于“中控台”—司机和前排...