Android自定义View实现公交成轨迹图

本文实例为大家分享了Android自定义View实现公交成轨迹图的具体代码,供大家参考,具体内容如下

总体分析下:水平方向recyclewview,item包含定位点,站台位置和站台名称。

下面看实现:

1.继承framelayout,实现构造方法:

public class BusStopPlateView extends FrameLayout {
...
 public BusStopPlateView(@NonNull Context context) {
  super(context);
  initView(context);
 }

 public BusStopPlateView(@NonNull Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  initView(context);
 }

 public BusStopPlateView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView(context);
 }
 private void initView(Context context) {
 ...
 //设置recycleview
 LayoutInflater.from(context).inflate(R.layout.xxx, this, true);
  mRecyclerView = (RecyclerView) findViewById(R.id.recycle);
  mRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
  mBusStopPlateAdapter = new BusStopPlateAdapter(mStationList);
  mRecyclerView.setAdapter(mBusStopPlateAdapter);

 ...
}

...
}

2.recycleview适配器:初始化的时候设置起点设置终点设置车道设置当前车位置的下标

 /**
  * 设置车道
  */
 private void setDriveway(BaseViewHolder helper, BusStopPlateStationInfo item) {
  if (helper.getAdapterPosition() <= adminCurrentIndex) {
   helper.getView(R.id.v_daolu).setSelected(true);
   helper.getView(R.id.iv_jiantou).setSelected(true);
  } else {
   helper.getView(R.id.v_daolu).setSelected(false);
   helper.getView(R.id.iv_jiantou).setSelected(false);
  }
 }

 /**
  * 设置起点
  */
 private void setStartStation(BaseViewHolder helper, BusStopPlateStationInfo item) {
  helper.setVisible(R.id.v_daolu, false)
    .setBackgroundRes(R.id.iv_jiantou, R.drawable.bg_busstop_vdaolu_start);
 }

 /**
  * 设置终点
  */
 private void setEndStation(BaseViewHolder helper, BusStopPlateStationInfo item) {
  helper.setBackgroundRes(R.id.iv_jiantou, R.drawable.bg_busstop_vdaolu_end)
    .setBackgroundRes(R.id.v_daolu, R.drawable.bg_busstop_vdaolu_end)
    .setVisible(R.id.v_zhanwei, true)
    .setVisible(R.id.v_daoli_zhanwei, false);
 }

 /**
  * 设置当前所在站点
  */
 private void setCurrentStation(BaseViewHolder helper, BusStopPlateStationInfo item) {
  mCurrentView = helper.getConvertView();
  helper.setVisible(R.id.bus_stop_reach, true)
    .setVisible(R.id.iv_bus_stop_current, false)
    .setVisible(R.id.tv_bus_stop_current_num, false)
    .setVisible(R.id.iv_current_point, true)
    .setVisible(R.id.iv_admin_index, true)
    // 显示占位符,用于显示一半的灰色
    .setBackgroundRes(R.id.v_daoli_zhanwei, R.drawable.bg_busstop_vdaolu)
    .setVisible(R.id.v_daoli_zhanwei, true);
//    .setTextColor(R.id.tv_bus_station_name, Color.parseColor("#3D93FD"));

  Glide.with(mContext)
    .load(R.drawable.bus_icon_fangxiang_current)
    .crossFade()
    .into((ImageView) helper.getView(R.id.iv_current_point));

  List<AliveBusInfo> aliveBusInfos = item.getAliveBusInfos();
  if (aliveBusInfos != null && aliveBusInfos.size() != 0) {
   AliveBusInfo aliveBusInfo = aliveBusInfos.get(0);
   if ("1".equals(aliveBusInfo.getStStatus()) && aliveBusInfo.getStName().equals(item.getStName())) {
    helper.setVisible(R.id.iv_admin_index, false)
      .setVisible(R.id.iv_bus_stop_current, true)
      .setImageResource(R.id.iv_bus_stop_current, R.drawable.bus_stop_current);
   }
  } else {
   Glide.with(mContext)
     .load(R.drawable.icon_admin_current_station)
     .crossFade()
     .into((ImageView) helper.getView(R.id.iv_admin_index));
  }

 }

 /**
  * 设置公交所在站点
  */
 private void setBusStation(BaseViewHolder helper, BusStopPlateStationInfo item) {
  List<AliveBusInfo> aliveBusInfos = item.getAliveBusInfos();
  if (aliveBusInfos != null && aliveBusInfos.size() != 0) {
   AliveBusInfo aliveBusInfo = aliveBusInfos.get(0);
   if ("0".equals(aliveBusInfo.getStStatus())) {
    // 在车道上
    helper.setVisible(R.id.bus_stop_not_to, true)
      .setVisible(R.id.bus_stop_reach, false)
      .setText(R.id.tv_stop_not_to_num, String.valueOf(aliveBusInfos.size()))
      // 显示在过道中的车
      .setVisible(R.id.iv_stop_not_to, aliveBusInfos.size() != 0)
      // 是否显示数字
      .setVisible(R.id.tv_stop_not_to_num, aliveBusInfos.size() > 1);
    // 如果已经过站 显示灰色图标
    if (aliveBusInfo.getStCount() < 0) {
     GlideUtils.loadImageView(mContext, R.drawable.bus_stop_over_station_min, helper.getView(R.id.iv_stop_not_to));
    } else {
     GlideUtils.loadImageView(mContext, R.drawable.bus_stop_not_to, helper.getView(R.id.iv_stop_not_to));
    }

   } else if ("1".equals(aliveBusInfo.getStStatus())) {
    // 到站
    helper.setVisible(R.id.bus_stop_not_to, false)
      .setVisible(R.id.bus_stop_reach, true)
      .setVisible(R.id.iv_admin_index, true)
      .setVisible(R.id.iv_bus_stop_current, false)
      .setVisible(R.id.tv_bus_stop_current_num, aliveBusInfo.getStCount() > 1)
      .setText(R.id.tv_bus_stop_current_num, String.valueOf(aliveBusInfos.size()));
    // 如果已经过站 显示灰色图标
    if (aliveBusInfo.getStCount() < 0) {
     GlideUtils.loadImageView(mContext, R.drawable.bus_stop_over_station, helper.getView(R.id.iv_admin_index));
    } else {
     GlideUtils.loadImageView(mContext, R.drawable.bus_stop_not_to, helper.getView(R.id.iv_admin_index));
    }
   }
  } else {
   // 隐藏公交车
   helper.setVisible(R.id.bus_stop_not_to, false)
     .setVisible(R.id.bus_stop_reach, false);
  }
 }

3.外部activity的点击事件:点击文字的时候将当前位置对象刷新到选择的位置,刷新recycleview

mBusStopPlateView.setOnBusStopPlateViewItemClick(new BusStopPlateView.onBusStopPlateViewEvent() {
   @Override
   public void onItemClick(BusStopPlateStationInfo station) {
    stationId = station.getStId();
    stationName = station.getStName();
    exportStationInfo(mBusStopPlateView.getStationList());
    aliveBusRefresh();

    //当上车提醒保存的信息与当前候车站点信息不一致时恢复为上车提醒,
    // 并在点击上车提醒是判断是否更新上车提醒的站点
    BusRemind remind = SpKeyConfig.getOnRemind();
    if (remind != null) {
     if (remind.getStationId().equals(stationId) &&
       remind.getLineId().equals(mLineId)) {
      tvOnRemind.setText("取消提醒");
      ivOnRemind.setImageResource(R.drawable.bus_icon_onremind_on);
     } else {
      tvOnRemind.setText("上车提醒");
      ivOnRemind.setImageResource(R.drawable.bus_icon_onremind_off);
     }
    }
   }

   @Override
   public void onCurrentViewPosition(int x, int y, boolean isVisibility) {
    mIvPoint.setTranslationX(x - mIvPoint.getWidth() / 2 + 6);
    mIvPoint.setVisibility(isVisibility ? View.VISIBLE : View.INVISIBLE);
   }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android中SurfaceView和view画出触摸轨迹

    一.引言          想实现一个空白的画板,上面可以画出手滑动的轨迹,就这么一个小需求.一般就来讲就两种实现方式,view或者surfaceview.下面看看两种是如何实现的. 二.实现原理          先简单说一下实现原理:        (1)用一张白色的Bitmap作为画板        (2)用canvas在bitmap上画线        (3)为了画出平滑的曲线,要用canvas的drawPath(Path,Paint)方法.        (4)同时使用贝塞尔曲线来使曲

  • 解决Android SurfaceView绘制触摸轨迹闪烁问题的方法

    本文分享了解决SurfaceView触摸轨迹闪烁问题的方法,供大家参考,具体内容如下 第一种解决SurfaceView触摸轨迹闪烁问题的方法: 由于SurfaceView使用双缓存机制,两张画布轮流显示到屏幕上.那么,要存储触摸轨迹并避免两张画布内容不一致造成的闪烁问题,完全可以利用保存绘制过程并不断重新绘制的方法解决闪烁,而且这样还顺带解决了多次试验中偶尔出现的因为moveTo()函数不能读取到参数执行默认设置(参数设为上次的触摸点)而出现的断线连接闪烁问题,详细代码如下: package c

  • Android自定义View实现公交成轨迹图

    本文实例为大家分享了Android自定义View实现公交成轨迹图的具体代码,供大家参考,具体内容如下 总体分析下:水平方向recyclewview,item包含定位点,站台位置和站台名称. 下面看实现: 1.继承framelayout,实现构造方法: public class BusStopPlateView extends FrameLayout { ... public BusStopPlateView(@NonNull Context context) { super(context);

  • Android自定义View实现天气预报折线图

    本文实例为大家分享了Android自定义View画天气预报折线图的具体代码,供大家参考,具体内容如下 效果图如下: 刚开始尝试用第三方画曲线的框架来画效果图,后来发现曲线间的阴影当有负数的度数的时候画不出来,而且不需要点击放大.点点可点的效果,用框架显得很臃肿,所以最后用自定义View来画的折线图.自定义画折线图的大致思路:这个图是有多个四边形组成的(4个点连接起来就是一个四边形),两边延伸:添加四个多余的点,将左右的边距设置成负数即可. 代码如下: public class WeatherCh

  • Android自定义View实现折线图效果

    下面就是结果图(每种状态用一个表情图片表示): 一.主页面的布局文件如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height=&quo

  • Android自定义View之渐变色折线图的实现

    目录 前言 如何实现 总结 前言 在之前的项目中,有做过一个需求,需要实现一个颜色渐变的折线图.当时项目中使用的图表库是MPAndroidChart,但是该库没有提供合适的方法来实现想要的效果,因此只能通过自定义view来实现. 通过这篇文章记录一下,便于之后需要实现类似的效果时查找使用. 如何实现 通过创建LinearGradient来实现颜色渐变,并将之设置到画笔Paint的着色器Shader,绘制想要的路径即可实现该效果. 实现代码如下: class GradientLineChart :

  • Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又称减幅振动.衰减振动.[1] 不论是弹簧振子还是单摆由于外界的摩擦和介质阻力总是存在,在振动过程中要不断克服外界阻力做功,消耗能量,振幅就会逐渐减小,经过一段时间,振动就会完全停下来.这种振幅随时间减小的振动称为阻尼振动.因为振幅与振动的能量有关,阻尼振动也就是能量不断减少的振动.阻尼振动是非简谐运

  • Android 自定义view实现水波纹动画效果

    在实际的开发中,很多时候还会遇到相对比较复杂的需求,比如产品妹纸或UI妹纸在哪看了个让人兴奋的效果,兴致高昂的来找你,看了之后目的很明确,当然就是希望你能给她: 在这样的关键时候,身子板就一定得硬了,可千万别说不行,爷们儿怎么能说不行呢: 好了,为了让大家都能给妹纸们想要的,后面会逐渐分享一些比较比较不错的效果,目的只有一个,通过自定义view实现我们所能实现的动效: 今天主要分享水波纹效果: 1.标准正余弦水波纹: 2.非标准圆形液柱水波纹: 虽说都是水波纹,但两者在实现上差异是比较大的,一个

  • Android自定义view制作绚丽的验证码

    废话不多说了,先给大家展示下自定义view效果图,如果大家觉得还不错的话,请继续往下阅读. 怎么样,这种验证码是不是很常见呢,下面我们就自己动手实现这种效果,自己动手,丰衣足食,哈哈~ 一. 自定义view的步骤 自定义view一直被认为android进阶通向高手的必经之路,其实自定义view好简单,自定义view真正难的是如何绘制出高难度的图形,这需要有好的数学功底(后悔没有好好学数学了~),因为绘制图形经常要计算坐标点及类似的几何变换等等.自定义view通常只需要以下几个步骤: 写一个类继承

  • Android自定义View详解

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View,可能都是比较恐惧的,但是这又是高手进阶的必经之路,所有准备在自定义View上面花一些功夫,多写一些文章.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 [ 3.重写onMesure ] 4.重写onDraw 我把3用[]标出了,所以说3不一

  • Android自定义View绘制随机生成图片验证码

    本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

  • Android自定义View绘制的方法及过程(二)

    上一篇<Android 自定义View(一) Paint.Rect.Canvas介绍>讲了最基础的如何自定义一个View,以及View用到的一些工具类.下面讲下View绘制的方法及过程 public class MyView extends View { private String TAG = "--------MyView"; private int width, height; public MyView(Context context, AttributeSet a

随机推荐