笔记43 | Android加载器Adapter的深入学习篇(二)

地址

csdn:http://blog.csdn.net/xiangyong_1521/article/details/78656841 简书:http://www.jianshu.com/p/abb1124a00a6


目录

  • 功能需求
  • 一步一步实现
  • 主要代码

功能介绍

A.绿色区域是选项内容信息

B.蓝色区域是控制和状态信息区域

需求

A.每次进入程序界面,需要将蓝色区域的状态信息更新到实时状态

B.点击< >按钮实现控制


一步一步实现

1.新建两个list用于存储选项内容和状态信息

private List<Integer> lists = new ArrayList<Integer>();
    private List<Integer> points = new LinkedList<Integer>();
...
    titles = getResources().getStringArray(R.array.title_set);
        TypedArray array = getResources().obtainTypedArray(R.array.total);
        for (int i = 0; i < titles.length; i++) {
            lists.add(array.getResourceId(i, 0));
            points.add(0);
        }

Strings.xml:

<string-array name="title_set">
        <item>感应式雨刷</item>
        <item>自动上锁模式</item>
     ...
    </string-array>

    <integer-array name="total">
        <item>@array/array1</item>
        <item>@array/array2</item>
      ...
    </integer-array>

    <string-array name="array1">
        <item>关闭</item>
        <item>打开</item>
    </string-array>
    <string-array name="array2">
        <item>关闭</item>
        <item>锁定:行驶时</item>
        <item>锁定:行驶时  解锁:熄火</item>
        <item>锁定:退出订车档  解锁:进入驻车档</item>
        <item>退出驻车档</item>
    </string-array>
   ...

2.用一个定时器实时扫描实时数据:

private Timer mTimer = null;
    private TimerTask mTimerTask = null;

    public static long mTickForShow;
    public long mTickForDoorShow;

    public void ontime() {
        if (this.mTimerTask != null)
            this.mTimerTask.cancel();

        if (this.mTimer == null)
            this.mTimer = new Timer();

        this.mTimerTask = new TimerTask() {
            public void run() {
                upDateView();
            }
        };
        this.mTimer.schedule(this.mTimerTask, 10L, 200L);
    }

byte[] g_can_carinfo=new byte[8];
private void upDateView() {
    byte data0 = g_can_carinfo[0];
...
//data0
        points.set(0, (((data0>>7)&0x01)&0xff));//感应式雨刷==============0 
        points.set(1, (((data0>>4)&0x07)&0xff));//自动上锁模式===============1
...
}

通过以上两步,当底层数据以 byte数据的形式传到应用用,通过定时器ontime()方法时候扫描,以获得一个二进制数据,存到points中;lists则用于存储选项文本内容;

3.然后重写一个BaseAdapter以加载用于将数据加载到ListView中,通过

adapter = new CarSetAdapter(getActivity(),titles,lists,points);

将数据传到adapter

private String[] titles;
    private List<Integer> lists;
    private List<Integer> points;//data updata
    private Context context;

    public CarSetAdapter(Context context,String[] titles, List<Integer> lists,List<Integer> points) {
        this.titles = titles;
        this.lists = lists;
        this.context = context;
        this.points = points;
    }
...
@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView==null){
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            holder.blankTextView = (BlankTextView) convertView.findViewById(R.id.blt);
            holder.title = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.title.setText(titles[position]);
        holder.blankTextView.init(points.get(position), null, lists.get(position),position);
        holder.blankTextView.addListener(this);
        return convertView;
    }

选项内容信息通过holder.title.setText(titles[position]);实现了加载,而右侧的控制区域,我们重写一个布局类BlankTextView,holder.blankTextView.init(points.get(position), null, lists.get(position),position);将对应的信息传到中国自定义布局里;

4.自定义布局BlankTextView:

private String getString(int index){
        if(arrayList.length>index){
            return arrayList[index];
        }
        return "";
    }

    private String key;
    private int current;
    public int id;
    private String[] arrayList;
    private int position;
    public void init(int current,String key,int id,int position){
        this.position = position;
        this.current = current;
        this.id = id;
        this.key = key;
        arrayList = context.getResources().getStringArray(id);//返回与特定资源ID关联的字符串数组。
        detail.setText(getString(current)); //显示按钮中间的信息
    }

    public void upDate(int current){
        this.current = current;
        detail.setText(getString(current));
    }

到了此处,就完成了状态信息的加载;

5.下面要实现两侧的点击监听,首先需要在自定义布局BlankTextView implements View.OnClickListener,实现两侧按钮的监听

@Override
    public void onClick(View view) {
        if (view==left) {
                current = current-1;
                current = (current>=0)?current:arrayList.length-1;
                if(position==5){
                    detail.setText(getString(current));
                }
                if (listener!=null) {
                    listener.left(current,id,position);
                }
        }

        if (view==right) {
                current = current+1;
                current = (current>=arrayList.length)?0:current;
                if(position==5){
                    detail.setText(getString(current));
                }
                if (listener!=null) {
                    listener.right(current,id,position);
                }
        }
    }

点击事件中,处理current值,然后再向外部提供一个监听接口,用来将处理的current回调

public interface BlankTextListener{
        public void right(int current,int id,int position);
        public void left(int current,int id,int position);
    }

    BlankTextListener listener;
    public void addListener(BlankTextListener listener){
        this.listener = listener;
    }

6.然后在Adapter中,拿到BlankTextListener接口,得到current并下发命令

@Override
    public void right(int current, int id,int position) {
        Log.i("md", "====right::"+current+"====position="+position);
        sendCommend(current,position);
    }

    @Override
    public void left(int current, int id,int position) {
        Log.i("md", "====left::"+current+"====position="+position);
        sendCommend(current,position);
    }
...
private void sendCommend(int current,int position){
        switch (position) {
        case 0:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x00, (byte)current);//感应式雨刷
            break;
        case 1:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x02, (byte)current);//自动上锁模式
            break;
...
}

当命令下发给底层,底层处理后会将最新的状态指令上发到应用层,通过方法2中的监听实现蓝色区域状态信息的更新,这样整个工作流程就完成了;


主要代码

Fragment

public class Pager1 extends Fragment {

    private ListView lv;
    private String[] titles;
    private List<Integer> lists = new ArrayList<Integer>();
    private List<Integer> points = new LinkedList<Integer>();
    private CarSetAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.carsetting, null);
        this.initData();
        this.initView(view);
        this.runTime();
        return view;
    }

    @SuppressLint("Recycle") 
    private void initData() {
        titles = getResources().getStringArray(R.array.title_set);
        TypedArray array = getResources().obtainTypedArray(R.array.total);
        for (int i = 0; i < titles.length; i++) {
            lists.add(array.getResourceId(i, 0));
            points.add(0);
        }
        Log.i("md", "md:lists  "+lists);
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    private void initView(View view) {
        lv = (ListView) view.findViewById(R.id.listview);
        lv.setOverScrollMode(View.OVER_SCROLL_NEVER);
        adapter = new CarSetAdapter(getActivity(),titles,lists,points);
        lv.setAdapter(adapter);
    }

    private void runTime(){
        new Thread(){
            @Override
            public void run() {
                handler1.sendEmptyMessageDelayed(3001, 30);
            }
        }.start();
    }

    @SuppressLint("HandlerLeak")
    private Handler handler1 = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            handler1.removeMessages(3001);
            if(WindowService_7010.carinfoChange){
                upDateView();
                WindowService_7010.carinfoChange = false;   
            }
            handler1.sendEmptyMessageDelayed(3001, 100);
        }
    };

    private void upDateView() {
        byte data0 = WindowService_7010.g_can_carinfo[0];
        byte data1 = WindowService_7010.g_can_carinfo[1];
        byte data2 = WindowService_7010.g_can_carinfo[2];
        byte data3 = WindowService_7010.g_can_carinfo[3];
        byte data4 = WindowService_7010.g_can_carinfo[4];
        byte data5 = WindowService_7010.g_can_carinfo[5];
        byte data6 = WindowService_7010.g_can_carinfo[6];
        byte data7 = WindowService_7010.g_can_carinfo[7];
        //data0
        points.set(0, (((data0>>7)&0x01)&0xff));//感应式雨刷==============0 
        points.set(1, (((data0>>4)&0x07)&0xff));//自动上锁模式===============1
        points.set(2, (((data0>>2)&0x03)&0xff));//无钥匙锁车提示音量===============2
        points.set(3, ((data0&0x03)&0xff));//自动重锁时间 ===========3
        //data1
        points.set(4, (((data1>>7)&0x01)&0xff));//解锁模式==============4
        points.set(5, (((data1>>6)&0x01)&0xff));//离车车锁==============5
        points.set(6, (((data1>>5)&0x01)&0xff));//三次闪灯转向信号==============6
        points.set(7, (((data1>>4)&0x01)&0xff));//转向信号音量==============7
        points.set(8, (((data1>>2)&0x03)&0xff));//车门打开时-车内灯自动熄灭==============8
        points.set(9, ((data1&0x03)&0xff));//车门关闭时-车内灯自动熄灭==============9
        //data2
        points.set(10, (((data2>>7)&0x01)&0xff));//自适应转向前照灯系统=============10
        points.set(11, (((data2>>6)&0x01)&0xff));//驾驶显示 亮度控制=============11
        points.set(12, (((data2>>5)&0x01)&0xff));//驾驶显示 主动驾驶显示=============12
        points.set(13, (((data2>>4)&0x01)&0xff));//驾驶显示 导航==============13
        points.set(14, (((data2>>3)&0x01)&0xff));//智能城市刹车系统==============14
        points.set(15, (((data2>>2)&0x01)&0xff));//燃油经济性 同步平均和里程==============15
        points.set(16, ((data2&0x03)&0xff));//盲点监控音量==============16
        //data3
        points.set(17,(((data3>>6)&0x03)&0xff));//车灯未关提醒器==============17
        points.set(18,(((data3>>3)&0x07)&0xff));//大灯关闭定时器==============18
        points.set(19,((data3&0x07)&0xff));//自动大灯开启=============19
//        data4
        points.set(20,(data4&0xff));//驾驶显示 高度==============20
//        data5
        points.set(21,(data5)&0xff);//驾驶显示 亮度==============21
//        data6
        points.set(22,(data6&0xff));//驾驶显示 校准=============22
        Log.i("md", "md:points  "+points);
        adapter.upData(points);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        handler1.removeMessages(3001);
    }
}

CarSetAdapter

public class CarSetAdapter extends BaseAdapter implements BlankTextListener{

    private String[] titles;
    private List<Integer> lists;
    private List<Integer> points;//data updata
    private Context context;

    public CarSetAdapter(Context context,String[] titles, List<Integer> lists,List<Integer> points) {
        this.titles = titles;
        this.lists = lists;
        this.context = context;
        this.points = points;
    }

    public void upData(List<Integer> points){
        this.points = points;
        this.notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return titles.length;
    }

    @Override
    public Object getItem(int position) {
        return lists.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView==null){
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            holder.blankTextView = (BlankTextView) convertView.findViewById(R.id.blt);
            holder.title = (TextView) convertView.findViewById(R.id.name);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        holder.title.setText(titles[position]);
        holder.blankTextView.init(points.get(position), null, lists.get(position),position);
        holder.blankTextView.addListener(this);
        return convertView;
    }

    private class ViewHolder{
        BlankTextView blankTextView;
        TextView title;
    }

    @Override
    public void right(int current, int id,int position) {
        Log.i("md", "====right::"+current+"====position="+position);
        sendCommend(current,position);
    }

    @Override
    public void left(int current, int id,int position) {
        Log.i("md", "====left::"+current+"====position="+position);
        sendCommend(current,position);
    }

    public static int type = 0;
    private void sendCommend(int current,int position){
        switch (position) {
        case 0:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x00, (byte)current);//感应式雨刷
            break;
        case 1:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x02, (byte)current);//自动上锁模式
            break;
        case 2:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x01, (byte)current);//无钥匙锁车提示音量
            break;
        case 3:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x03, (byte)(current));//自动重锁时间
            break;
        case 4:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x04, (byte)current);//解锁模式
            break;
        case 5:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x05, (byte)(current));//离车车锁
            break;
        case 6:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x06, (byte)(current));//三次闪灯转向信号
            break;
        case 7:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x07, (byte)current);//转向信号音量
            break;
        case 8:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x08, (byte)(current));//车门打开时-车内灯自动熄灭
            break;
        case 9:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x09, (byte)current);//车门关闭时-车内灯自动熄灭
            break;
        case 10:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0a, (byte)(current));//自适应转向前照灯系统
            break;
        case 11:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0f, (byte)current);//驾驶显示:亮度控制
            break;
        case 12:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x11, (byte)current);//驾驶显示:主动驾驶显示
            break;
        case 13:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x12, (byte)(current));//驾驶显示:导航
            break;
        case 14:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x14, (byte)(current));//智能城市刹车系统
            break;
        case 15:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x16, (byte)(current));//燃油经济性:同步平均和里程
            break;
        case 16:

            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x15, (byte)(current));//盲点监控音量
            break;
        case 17:

            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0b,  (byte)(current));//车灯未关提醒器
            break;
        case 18:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0c, (byte)(current));//大灯关闭定时器
            break;
        case 19:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0d, (byte)(current));//自动大灯开启
            break;
        case 20:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x0e, (byte)(current));//驾驶显示:高度
            break;
        case 21:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x10, (byte)(current));//驾驶显示:亮度
            break;
        case 22:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x13, (byte)(current));//驾驶显示:校准
            break;

        default:
            SendGmcm.sendCommendFromData((byte)0x84, (byte)0x18, (byte)(current));//驾驶显示:校准
            break;
        }
    }
}

BlankTextView:

//md 2016 5/17
public class BlankTextView extends RelativeLayout implements View.OnClickListener{

    private Context context;
    public BlankTextView(Context context, AttributeSet arg1, int arg2) {
        super(context, arg1, arg2);
        this.context = context;
        this.initView();
    }

    public BlankTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.initView();
    }

    public BlankTextView(Context context) {
        super(context);
        this.context = context;
        this.initView();
    }

    private String getString(int index){
        if(arrayList.length>index){
            return arrayList[index];
        }
        return "";
    }

    private String key;
    private int current;
    public int id;
    private String[] arrayList;
    private int position;
    public void init(int current,String key,int id,int position){
        this.position = position;
        this.current = current;
        this.id = id;
        this.key = key;
        arrayList = context.getResources().getStringArray(id);//返回与特定资源ID关联的字符串数组。
        detail.setText(getString(current)); //显示按钮中间的信息
    }

    public void upDate(int current){
        this.current = current;
        detail.setText(getString(current));
    }

    private TextView detail;
    private ImageView left,right;
    private void initView() {
        View view = LayoutInflater.from(context).inflate(R.layout.blank_text, null);
        this.addView(view);
        detail = (TextView) view.findViewById(R.id.time_text);
        left = (ImageView) view.findViewById(R.id.time_lift);
        right = (ImageView) view.findViewById(R.id.time_right);
        left.setOnClickListener(this);
        right.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (view==left) {
                current = current-1;
                current = (current>=0)?current:arrayList.length-1;
                if(position==5){
                    detail.setText(getString(current));
                }
                if (listener!=null) {
                    listener.left(current,id,position);
                }
        }

        if (view==right) {
                current = current+1;
                current = (current>=arrayList.length)?0:current;
                if(position==5){
                    detail.setText(getString(current));
                }
                if (listener!=null) {
                    listener.right(current,id,position);
                }
        }
    }

    public interface BlankTextListener{
        public void right(int current,int id,int position);
        public void left(int current,int id,int position);
    }

    BlankTextListener listener;
    public void addListener(BlankTextListener listener){
        this.listener = listener;
    }
}

blank_text.xml

<?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" >

    <ImageView
        android:id="@+id/time_lift"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="5dp"
        android:layout_toLeftOf="@+id/time_text"
        android:src="@drawable/lift_select_selector" />

    <TextView
        android:id="@+id/time_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginRight="5dp"
        android:layout_toLeftOf="@+id/time_right"
        android:background="@drawable/xianshitiao"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="15sp" />

    <ImageView
        android:id="@+id/time_right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:src="@drawable/right_select_selector" />
</RelativeLayout>

item.xml:

<?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:paddingBottom="5dp"
    android:paddingTop="5dp" >

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="25dp"
        android:clickable="false"
        android:gravity="center_vertical"
        android:textColor="@android:color/white"
        android:textSize="18sp" />

    <com.can.mazda.util.BlankTextView
        android:id="@+id/blt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="25dp" />

</RelativeLayout>

原文发布于微信公众号 - 项勇(xiangy_life)

原文发表时间:2017-11-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏飞扬的花生

jsencrypt参数前端加密c#解密

      写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度...

3859
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2000
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2667
来自专栏芋道源码1024

熔断器 Hystrix 源码解析 —— 断路器 HystrixCircuitBreaker

本文主要基于 Hystrix 1.5.X 版本 1. 概述 2. HystrixCircuitBreaker 3. HystrixCircuitBreaker....

5277
来自专栏ASP.NETCore

ASP.NET Core 整合Autofac和Castle实现自动AOP拦截

除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninjec...

674
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2506
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2112
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4808
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2622
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4054

扫码关注云+社区