`
lesterlester
  • 浏览: 3553 次
社区版块
存档分类
最新评论
阅读更多
<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

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

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

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

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

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

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

    比如在教室内,若要指定一个学生的座位,我们可以说“第2排第3座”,在这里,“排数”相当于x坐标,“座数”相当于y坐标,用有序数对表示就是(2,3)。同样,在电影院中,一个座位可以通过“12排8座”来指定,即(12,8)...

    七年级数学下册第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图标的尺寸增加...

    (最新)人教版初中数学第七章平面直角坐标系导学案.pdf

    拓展探究部分可能会涉及更复杂的定位问题,如使用雷达探测目标位置,或者象棋盘上棋子的位置定位。 总结来说,这篇导学案的编写目的是帮助学生深刻理解并掌握平面直角坐标系和有序数对的概念。这不仅对于解决二维...

    直升机介绍学习教案.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. 象棋中的位置表示: - "相"走一步不能跨越其他棋子,所以其位置...

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

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

Global site tag (gtag.js) - Google Analytics