笔记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 条评论
登录 后参与评论

相关文章

来自专栏7号代码

Android应用界面开发——ListView,GridView,ScrollView

ListView的意思是列表视图,是应用最广泛的一种视图,例如联系人,功能列表,菜单等等都会用到ListView。

733
来自专栏青蛙要fly的专栏

关于Fragment的动态添加的相关疑问及解答

今天在网上看到了一个开源库:Spruce Android Animation Library (and iOS)

662
来自专栏向治洪

android下拉加载更多

新浪微博,和QQ空间里面,都有那个下拉刷新的效果,另很多人眼前一亮,细细分析,原理原来如此。 在原作者的基础上,写了一些注释,和帮助大家更好的阅读理解,(可...

2116
来自专栏Android开发指南

2.SlidingMenu(侧边栏效果)

34310
来自专栏开发之途

Android 仿360悬浮球与加速球

1708
来自专栏Android知识点总结

5-AVI--Fragment简单封装

823
来自专栏向治洪

gradeview可拖动效果实现

下面先上这次实现功能的效果图:(注:这个效果图没有拖拽的时候移动动画,DEMO里面有,可以下载看看) ? 一、开发心里历程 刚开始接触这个的时候,不知道要如何实...

2688
来自专栏飞雪无情的博客

Android GridView组件的使用

GridView是一个网络布局的视图,他能让你的元素显示在一个个的格子里。我们的桌面就是一个GridView。。

713
来自专栏小鄧子的技术博客专栏

【译】Activity分割动画如何使用我的动画##

在切换不同Activity时,系统级过渡动画是作用于整个Activity的,而我想要实现的动画效果是将Activity A分割成两部分,然后将他们向外推开,最后...

782
来自专栏Android干货

Android项目实战(十七):QQ空间实现(二)—— 分享功能 / 弹出PopupWindow

2776

扫码关注云+社区