`
lesterlester
  • 浏览: 3542 次
社区版块
存档分类
最新评论
阅读更多
<div class="iteye-blog-content-contain" style="font-size: 14px">

       由于涉及到工作内容保密的问题,所以无法提供源码,只能提供涉及该项功能的实现,本着开源和互相学习以及以后相同功能的重复利用的目的。

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>
0
0
分享到:
评论

相关推荐

    TRW:描绘半自动驾驶的技术前景.pdf

    TRW还研发了主动/可逆安全带技术,能够在碰撞时更有效地帮助管理乘员的身体动能,并且可以通过最新技术帮助乘员找到并扣好安全带、在车辆高速运动中拉紧织带、降低乘员偏离座位的风险。 德尔福作为另一家领先的...

    61探索确定位置的方法(xin).ppt

    首先,我们从上海大剧院的案例出发,理解了如何通过有序数对的方式来表示座位的位置。有序数对(排数,座数)是一个简单而有效的工具,用来描述二维平面上的精确位置。 对于确定位置,我们发现通常需要两个数据,即...

    探索确定位置的方法PPT课件.pptx

    在教室中,确定一个座位通常需要两个数据,即排数和座数,例如"第2排第3座"。而在电影院,同样的原则适用,如"12排8座"。如果只有排数而没有座数,我们无法准确找到位置,因为同一排可能有多个座位。 课件引入了一...

    【推荐】waymo自动驾驶资料大全.zip

    95第二排车辆优先座位 96智能部署自动驾驶汽车的安全机制 97面向车辆的乘客显示 98基于音频样本的警笛检测方法 99用于雷达的相位编码线性频率调制 100模拟虚拟对象 ………… 资料太多不一一列举了,共169份 报告...

    八年级上册数学第三章《确定位置》习题北师大版.pdf

    最后,雷达探测器和建筑区的例子展示了在实际应用中,位置可以用角度和距离来描述。例如,目标C、F的位置使用了角度和距离,而目标A、B、D、E的位置表示同样需要遵循这样的规则。 综上所述,《确定位置》这一章涵盖...

    七年级数学下册第14章位置与坐标14.4用方向和距离描述两个物体作业设计新版青岛版

    - 雷达站与小岛的位置描述中,A、B、C岛的位置需要给出相对于雷达站的方向和距离,例如A岛的位置可能是北偏东某一角度,距离雷达站某一千米。 4. **坐标与路径规划**: - 图形中的路线规划问题,如乐乐的移动路径...

    第七章平面直角坐标系课堂练习题及答案精选.doc

    8. **雷达目标**:雷达探测目标的位置通常使用极坐标表示,如C(6,120°)和F(5,210°)。而表示不正确的是D,因为角度应该是顺时针或逆时针从正北开始计算。 9. **正整数排列**:在特定的数列排列中,有序数对可以...

    民用航空英语词汇.doc

    26. 空中预警引导(AWACS, Airborne Warning and Control System):装备有先进雷达系统的军用飞机,用于空中监视和指挥。 27. 客用飞机(airliner, passenger aircraft):专门设计用于搭载乘客的飞机。 28. 远程...

    cinema-booking-system

    雷达 YDAR是一种电影院预订系统,使用OOP风格PHP和MYSQL(仍在仪表板和电影院管理员上工作)。 查看已部署的网站,请 特征 登录注册 将类别添加到您的帐户或将其删除。 选择电影院。 从“电影”页面中选择要观看的...

    车辆乘员检测参考设计电路。

    压力传感器则检测座椅上的重量变化,从而确定座位是否被占用。 在硬件设计上,这些传感器会与微控制器(MCU)相连,MCU负责处理传感器数据,进行信号处理和算法运算。MCU的选择通常需要考虑其处理能力、功耗和接口...

    AH64D-DocTest

    14/03/2021 修复了从ASE页面打开FCR页面的问题雷达最大检测范围从10K更改为8K 禁止火箭齐射以防止错误的是用海德拉斯(Hyas)射击的地狱火// TEMP // 添加了香草热传感器CFG红外传感器固定翼Cscope图标的尺寸增加...

    直升机介绍学习教案.pptx

    4. **安全装置**:配备有气象雷达、空中防撞系统、近地警告系统、遇险定位装置、浮筒、火警探测和灭火系统,确保飞行安全。 5. **客舱设施**:客舱内有照明、通风、加温和冷气系统,以及与驾驶舱通话装置。两侧有6...

    61探索确定位置的方法.ppt

    首先,通过一个学生座位表的例子,我们看到小刚的位置被标记为(5,2),这意味着他在第5列,第2行。这种坐标系统是基于笛卡尔坐标系,其中第一个数字代表列号,第二个数字代表行号,通常列号写在前面,行号写在后面...

    关于基于乘员存在和位置的自主驾驶行为的适应性的介绍说明.rar

    5. 车内环境理解:除了乘员存在和位置,系统还需要理解车内环境的整体情况,包括座位布局、物体位置等,以便在必要时进行干预,如开启空调、调整座椅或警告乘客注意安全。 6. 数据隐私与安全:收集和处理乘客数据的...

    2020春七年级数学下册第十四章位置与坐标14.4用方向和距离描述两个物体同步练习无答案新版青岛版202106171166

    例如,座位可以被描述为"第几排第几个座位"。这种确定位置的方法称为直角坐标系统,类似于平面直角坐标系中的x轴和y轴。 2. 在航海中,确定位置需要三个数据,分别是经度、纬度和深度。经度用来指示东西方向的位置...

    新人教(七下)第7章 平面直角坐标系 综合水平测试题2.doc

    1. 座位编号系统可以类比为坐标系统,如张艳的座位记为(2,4),意味着她在第2排第4列,王刚的位置为(5,8),则他在第5排第8列。 2. 点的坐标描述了它离坐标轴的距离:点A(3,-4)到y轴的距离是3,到x轴的距离...

    七年级数学下册第七章平面直角坐标系7.1平面直角坐标系7.1.1有序数对练习含解析新版新人教版20200528326

    - 座位情况可以用有序数对来表示,例如第一排第一列可以表示为(1, 1),以此类推,对于图7-1-1-2中的学生座位,可以根据位置用有序数对表示。 5. 象棋中的位置表示: - "相"走一步不能跨越其他棋子,所以其位置...

    海船船员培训场地设施设备标准.docx

    1. 多媒体教室用于理论教学,确保有足够的座位和教学资源。 2. 陈设室用于展示各种救生设备,如救生衣、防水保温服和气胀式救生筏。 3. 设有50米×25米游泳池,配备5米跳台,用于个人求生技能训练。 4. 模拟消防舱室...

    汽车行驶中的连接:射频通信

    另外,以后还会增加用于车辆与车辆和车辆与基础设施间通信的DSRC(专用短程通信,5.9GHz),也可能还有防碰撞雷达,不过这通常是一个单独系统。  用于所有这些设备的大多数电子电路都位于“中控台”—司机和前排...

Global site tag (gtag.js) - Google Analytics