精华内容
下载资源
问答
  • 一般开发过程中,我们会遇到这种需求,对列表某些条目进行点选,然后进行下一步操作,一般列表控件都没该功能,这里就需要我们去自定义了,本篇博文将进行归纳和总结。 先看下效果图 下面说下实现步骤 1....

    一般在开发过程中,我们会遇到这种需求,对列表的某些条目进行点选,然后进行下一步操作,一般列表控件都没该功能,这里就需要我们去自定义了,本篇博文将进行归纳和总结。

    先看下效果图

      

    下面说下实现步骤

    1.按照国际惯例,分析界面,画布局

    核心控件就是这个列表了,这里我们当然是用RecyclerView啦

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="40dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="选择界面"
                android:textSize="16sp" />
    
            <TextView
                android:id="@+id/main_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:padding="10dp"
                android:text="全选" />
        </RelativeLayout>
    
        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:background="@color/colorPrimaryDark" />
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/main_rl"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    
        <Button
            android:id="@+id/main_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="确定" />
    </LinearLayout>

    2.新建MainBean,我们这里比较简单,只有一个标题title和选中状态isSelect

    package com.fantasychong.selectlisttest0910;
    
    import java.io.Serializable;
    
    /*
     *Crated by yedona on 2018/9/10
     */
    public class MainBean implements Serializable {
        private String title;
        private boolean isSelect;
    
        @Override
        public String toString() {
            return "MainBean{" +
                    "title='" + title + '\'' +
                    ", isSelect=" + isSelect +
                    '}';
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public boolean isSelect() {
            return isSelect;
        }
    
        public void setSelect(boolean select) {
            isSelect = select;
        }
    
        public MainBean(String title, boolean isSelect) {
            this.title = title;
            this.isSelect = isSelect;
        }
    }
    

    3.新建适配器adapter,依旧继承BaseQuickAdapter。

    绘制item布局,一个title和一个圆点图片,圆点图片这里我们使用selector,当选中时显示

    反之显示

    xml文件如下

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/radio_choose" android:state_checked="true"/>
        <item android:drawable="@drawable/radio_normal" android:state_checked="false"/>
    </selector>

    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="60dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_centerVertical="true"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <LinearLayout
                android:id="@+id/item_main_ll"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingLeft="10dp"
                android:paddingRight="10dp">
    
                <ImageView
                    android:id="@+id/item_main_point"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:src="@drawable/radio_choose_select" />
            </LinearLayout>
    
            <TextView
                android:id="@+id/item_main_tv"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="今天天气很不错!!!" />
        </LinearLayout>
    
        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:layout_alignParentBottom="true"
            android:background="@color/colorPrimaryDark" />
    </RelativeLayout>

    在adapter中,除了常规title赋值外,有几个比较重要的方法

    a.圆点布局的点击事件,为了方便点击,特地给圆点图片外面套了一个布局,点击时改变该条item的选中状态(选中改为未选中,未选中改为选中),如果点击完后是选中状态就给图片赋radio_choose,反之赋radio_normal.

    ll.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            item.setSelect(!item.isSelect());
            iv.setImageResource(item.isSelect() ? R.drawable.radio_choose : R.drawable.radio_normal);
        }
    });

    b.自定义一个selectAll方法。将列表所有的item都设置为XX状态,结果取决于用户调用该方法时传递的isSelectAll值,为true则选中所有item,为false则取消选中所有item。

    public void selectAll(boolean isSelectAll) {
        for (MainBean bean : getData()) {
            bean.setSelect(isSelectAll);
        }
        notifyDataSetChanged();
    }

    c.自定义一个getSelectList()方法,用于获取当前点选的item的list

    public List<MainBean> getSelectList() {
        List<MainBean> list = new ArrayList<>();
        for (MainBean bean : getData()) {
            if (bean.isSelect()) {
                list.add(bean);
            }
        }
        return list;
    }

    4.准备工作都做完了,下面就可以在MainActivity中调用了。

    a.首先初始化控件。主要是设置右上角文字的点击事件,当前文字是"全选",则调用取消全选的功能,当前文字是'全不选", 则调用全选的功能。下方按钮的点击事件主要是将选择的item数据list传递给上一个页面,实际需求我们可以灵活调用,这里仅供展示。

    /**
     * 初始化控件
     */
    private void initView() {
        rl= findViewById(R.id.main_rl);
        tv= findViewById(R.id.main_tv);
        btn= findViewById(R.id.main_btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent= new Intent();
                intent.putExtra("data", adapter.getSelectList().toString());
                setResult(1, intent);
                finish();
            }
        });
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if("全选".equals(tv.getText().toString())){
                    tv.setText("全不选");
                    adapter.selectAll(true);
                }else{
                    tv.setText("全选");
                    adapter.selectAll(false);
                }
                Log.d("listdata", adapter.getSelectList().toString());
            }
        });
    }
    

    b.初始化列表list,默认都是没选中的

    /**
     * 初始化数据list
     */
    private void initList() {
        MainBean bean= new MainBean("是你给了我一把伞,撑住倾盆洒落的孤单", false);
        dataList.add(bean);
        MainBean bean1= new MainBean("所以好像给你一湾河岸,洗涤腐蚀心灵的遗憾", false);
        dataList.add(bean1);
        MainBean bean2= new MainBean("给你我所有的温暖,脱下唯一挡风的衣衫", false);
        dataList.add(bean2);
        MainBean bean3= new MainBean("思念刮过背脊打着冷颤,眼神依旧为你而点燃", false);
        dataList.add(bean3);
    }

    c.初始化适配器

    /**
     * 初始化适配器
     */
    private void initAdapter() {
        adapter= new MainAdapter(dataList);
        LinearLayoutManager manager= new LinearLayoutManager(this);
        rl.setLayoutManager(manager);
        rl.setAdapter(adapter);
    }
    

     

    MainActivity完整代码:

    package com.fantasychong.selectlisttest0910;
    
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        private RecyclerView rl;
        private TextView tv;
        private List<MainBean> dataList= new ArrayList<>();
        private MainAdapter adapter;
        private Button btn;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //初始化控件
            initView();
            //初始化数据list
            initList();
            //初始化适配器
            initAdapter();
    
        }
    
        /**
         * 初始化适配器
         */
        private void initAdapter() {
            adapter= new MainAdapter(dataList);
            LinearLayoutManager manager= new LinearLayoutManager(this);
            rl.setLayoutManager(manager);
            rl.setAdapter(adapter);
        }
    
        /**
         * 初始化控件
         */
        private void initView() {
            rl= findViewById(R.id.main_rl);
            tv= findViewById(R.id.main_tv);
            btn= findViewById(R.id.main_btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent intent= new Intent();
                    intent.putExtra("data", adapter.getSelectList().toString());
                    setResult(1, intent);
                    finish();
                }
            });
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if("全选".equals(tv.getText().toString())){
                        tv.setText("全不选");
                        adapter.selectAll(true);
                    }else{
                        tv.setText("全选");
                        adapter.selectAll(false);
                    }
                    Log.d("listdata", adapter.getSelectList().toString());
                }
            });
        }
    
        /**
         * 初始化数据list
         */
        private void initList() {
            MainBean bean= new MainBean("是你给了我一把伞,撑住倾盆洒落的孤单", false);
            dataList.add(bean);
            MainBean bean1= new MainBean("所以好像给你一湾河岸,洗涤腐蚀心灵的遗憾", false);
            dataList.add(bean1);
            MainBean bean2= new MainBean("给你我所有的温暖,脱下唯一挡风的衣衫", false);
            dataList.add(bean2);
            MainBean bean3= new MainBean("思念刮过背脊打着冷颤,眼神依旧为你而点燃", false);
            dataList.add(bean3);
        }
    }
    

     

    至此全部完成,附上demo

    资源下载

    展开全文
  • 2.向该工程增加引用:引用位于OUTPUT文件夹中NorthWind.dll td.Core.dll td.Security.dll 以及所有以DevExpress开头文件(由于界面使用了DEV控件,所以必须引用) ,添加.NET 文件System.Drawing System....
  • VB控件属性使用大全

    2011-12-15 12:02:34
    在Windows操作系统上,VisualBasic作为一门计算机语言,功能非常强大,而且简单易学...2、VisualBasic在科学计算、多媒体软件开发、网络应用等方面都有强大功能,尤其在数据库开发方面,提供了许多控件...
  • vc++ 开发实例源码包

    2014-12-16 11:25:17
    OPENG开发的示例代码c++版 演示了OpenG的使用方法,内含几个实例,一个实例就3个文件。 p2p vb实例。 p2p+technology 文档。 P2P视频技术源码(含开发文档) 目前的协议有如下一些特点: 1) 客户向服务器发送请求,...
  • Delphi5开发人员指南

    热门讨论 2012-07-18 16:51:14
    第一部分 快速开发的基础 第1章 Delphi 5下的Windows编程 1 1.1 Delphi产品家族 1 1.2 Delphi是什么 3 1.2.1 可视化开发环境 3 1.2.2 编译器的速度和已编译代码的效 率 4 1.2.3 编程语言的功能及其复杂性 4 1.2.4 ...
  • PT80-NEAT开发指南v1.1

    2014-06-24 18:38:34
    NEAT 程序一般执行过程 ..................................................................................................................... 20 第四章 窗口 ................................................
  • 6.3.2 使用AIDL开发程序的一般步骤 6.3.3 实现远程控制计数器示例 6.4 AIDL深入练习 6.4.1 服务端实现 6.4.2 客户端实现 6.5 系统服务 6.5.1 获得系统服务 6.5.2 获取屏幕分辨率 6.5.3 剪贴板服务 6.5.4 电话服务 ...
  • 新版Android开发教程.rar

    千次下载 热门讨论 2010-12-14 15:49:11
    � 基于 QEMU 开发的模拟器调试手段不十分丰富,只支持通话、SMS等,速度慢。 � 暂不具备 Push Mail 和 Office(DataViz 、 QuickOffice 计划近期推出 ) 功能,目前主要面向的是普通消费 者 用户,对商业用户支持...
  • D5开发人员指南-05卷

    2011-09-27 13:26:13
    21.1.2 编写组件的一般步骤 607 21.1.3 确定一个祖先类 608 21.1.4 创建一个组件单元 609 21.1.5 添加属性 609 21.1.6 加入事件 615 21.1.7 创建自定义的方法 619 21.1.8 构造器和析构器 619 21.1.9 注册组件 620 ...
  • 注意,此版本不包含源代码,只是一个绿色可以随时打开版本,开发工具为:delphi7+sqlserver2000我PDF(Perfect Developer Frame),想要 简单,快速,健壮,因此我用还是C/S结构,因为客户可不管你用是什么最高新...
  • 掌握开发Windows应用程序的一般过程。 【实验要求】 1.是一个标准的Windows应用程序,内容自定义。 2.要体现在实验目的中列出的控件的使用。 【实验步骤】(要求自己填写详细的实验步骤,设计思路和关键代码)...

    【实验目的】

          熟练使用windows基本控件的使用,如菜单、工具栏、状态栏、列表框、组合框、Tabcontrol和Listview等,并掌握其主要的事件、属性。掌握开发Windows应用程序的一般过程。

    【实验要求】

    1.是一个标准的Windows应用程序,内容自定义。

    2.要体现在实验目的中列出的控件的使用。

    【实验步骤】(要求自己填写详细的实验步骤,设计思路和关键代码)

    【实验体会及存在问题】(要求自己填写,感想、设计时碰到的问题,包括设计思想、调试等)

     

    这次实验报告时写个记事本,还是先看截图吧:

    1、首先是在主窗口FormMain.cs 下设置两个变量:2、新建:

      

     

    string currentFileName ="新建shang文档.txt";//这个变量来跟踪当前的文档名字
    bool changed =false;//判断文本是否改动

     

    代码
    privatevoid 新建ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    richTextBox1.Text
    ="";
    StreamWriter sw
    =new StreamWriter(currentFileName);
    sw.Close();
    //MessageBox.Show("hello");
    }

    3、打开

     

    代码
    privatevoid 打开ToolStripMenuItem_Click(object sender, EventArgs e)
    {

    openFileDialog1.InitialDirectory
    ="c:\\";//默认打开在c盘
    openFileDialog1.Filter ="txt files (*.txt)|*.txt|All files (*.*)|*.*";//文件类型
    //openFileDialog1.FilterIndex = 2;
    //openFileDialog1.RestoreDirectory = true;
    DialogResult dr =this.openFileDialog1.ShowDialog();

    if (dr == DialogResult.OK)
    {
    currentFileName
    = openFileDialog1.FileName;
    openFile(
    this.openFileDialog1.FileName);
    }
    }

    这里涉及到一个文件写入函数 openFile(string file) 其定义如下:

    代码
    privatevoid openFile(string file)
    {
    try
    {
    using (StreamReader sr =new StreamReader(file, Encoding.GetEncoding(0)))
    {
    string text ="";
    string line;
    while ((line = sr.ReadLine()) !=null)
    {
    text
    += line +"\n";//给读取的文本加上换行
    }
    this.richTextBox1.Text = text;//写入
    }
    }
    catch (Exception ex)
    {

    MessageBox.Show(ex.Message);
    }
    }

     

    4、好了,到保持了,保持是涉及到一个文件的读取,像刚刚文件写入一样,也用了一个函数writeFile(string file),它保持的位置是默认的

     

     

    代码
    privatevoid writeFile(string file)
    {
    using (StreamWriter sw =new StreamWriter(file))
    {
    foreach (string s in richTextBox1.Lines)
    {
    sw.WriteLine(s);
    }
    }
    }

    5、另存为,其实另存为的方法跟保持相似,前半段代码跟打开完全一样:

    代码
    privatevoid 另存为ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    saveFileDialog1.InitialDirectory
    ="c:\\";//默认打开在c盘
    saveFileDialog1.Filter ="txt files (*.txt)|*.txt|All files (*.*)|*.*";//文件类型
    DialogResult dr =this.saveFileDialog1.ShowDialog();
    if (dr == DialogResult.OK)
    {
    currentFileName
    = openFileDialog1.FileName;
    writeFile(
    this.saveFileDialog1.FileName);
    }
    }

    6、这步的页面设置是打印时候才有用到的,它用到了一个pageSetDialog控件,代码很简单,直接调用

    privatevoid 页面设置ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    pageSetupDialog1.ShowDialog();
    }

    7、打印,也是直接控件的调用,其中也PrintPreviewDialog是打印预览控件

    代码
    privatevoid 打印ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    //打印预览
    try
    {
    //对printPreviewDialog进行实例化可以解决报错
    PrintPreviewDialog printPreviewDialog1 =new PrintPreviewDialog();
    printPreviewDialog1.Show();
    //this.printDocument1.Print();
    }
    catch (Exception ex)
    {

    MessageBox.Show(ex.Message);
    //报错说无法访问已释放的printPreviewDialog
    }

    }

    8、编辑->撤消 撤消命令不用我们写Undo有聚成的直接用

    代码
    privatevoid 撤消ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    // Determine if last operation can be undone in text box.
    if (richTextBox1.CanUndo ==true)
    {
    // Undo the last operation.
    richTextBox1.Undo();
    // Clear the undo buffer to prevent last action from being redone.
    richTextBox1.ClearUndo();
    }

    }

    9、编辑->剪切  跟撤消一样,剪切也是集成的 cut方法直接调用

    代码
    privatevoid 剪切ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    // Ensure that text is currently selected in the text box.
    if (richTextBox1.SelectedText !="")
    // Cut the selected text in the control and paste it into the Clipboard.
    richTextBox1.Cut();

    }

    10、复制 同上

    11、粘贴

    代码
    privatevoid 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    // Determine if there is any text in the Clipboard to paste into the text box.
    if (Clipboard.GetDataObject().GetDataPresent(DataFormats.Text) ==true)//这边只粘贴文本
    {
    // Determine if any text is selected in the text box.
    if (richTextBox1.SelectionLength >0)
    {
    // Ask user if they want to paste over currently selected text.
    // if (MessageBox.Show("Do you want to paste over current selection?", "Cut Example", MessageBoxButtons.YesNo) == DialogResult.No)
    // Move selection to the point after the current selection and paste.
    richTextBox1.SelectionStart = richTextBox1.SelectionStart + richTextBox1.SelectionLength;//覆盖选中的
    }
    // Paste current text in Clipboard into text box.
    richTextBox1.Paste();
    }

    }

    12、查找 打开另一个窗口 FormSearch 这里有主副窗口的设定 这个很聪明,老师说主副窗口用一个全局变量会比较好,但我试过了,没做出来,等课程设计做好了再来搞这鬼东东.

        private void 查找ToolStripMenuItem_Click(object sender, EventArgs e)
        {
                FormSearch fs = new FormSearch(this );
                fs.Owner = this;
                fs.Show();

        }

    下面先来看看怎么设定主副窗口把 使之可以传参,就是在FormSearch的构造函数设定

      public FormSearch(FormMain f)//
            {
                this.Owner = f;
                InitializeComponent();
            }

     

    查找下一个按钮的代码:

    代码
    //怎样设置每次点击时,查询会自动跳到下一个要查询的字符串
    privatevoid btnNext_Click(object sender, EventArgs e)
    {

    FormMain fm
    =this.Owner as FormMain;

    string s1 = tbSeacher.Text;
    string s2 = fm.richTextBox1.Text;
    int res = s2.IndexOf(s1);
    if (!tbSeacher.Text.Trim().Equals(""))
    {
    while (res !=-1)
    {
    fm.richTextBox1.Select(res, s1.Length);
    fm.richTextBox1.Focus();
    //把焦点设置在formmain的文本框中
    System.Threading.Thread.Sleep(1000);//间隔1秒
    res = s2.IndexOf(s1, res +1);//如果找不到时res值为-1
    }
    }
    MessageBox.Show(
    "没有找到!");
    }
    代码

    privatevoid 字体ToolStripMenuItem_Click(object sender, EventArgs e)
    {
    FontDialog fd
    =new FontDialog();
    DialogResult dr
    = fd.ShowDialog();
    if (dr==DialogResult.OK)
    {
    richTextBox1.Font
    = fd.Font;
    }
    }

     

     14、字体颜色跟字体一样 要用到一个ColorDialog控件

    。。。

    当然还有其他的,比如说工具栏啦 状态栏啦 还有listview控件...等等 我觉得这些没意思 就不想写了。。好了,先这样,要去做网页了。。。。

     

     

     

     

     

     

     

     

     

    13、接下来看看字体怎么设置吧 它用到了一个FontDialog控件

    转载于:https://www.cnblogs.com/huaizuo/archive/2010/12/06/1898128.html

    展开全文
  • ASP.NET网页代码模型及生命周期

    热门讨论 2009-07-28 14:22:11
    在【位置】选项中,旁边的【下拉菜单】可以按照开发的需求来写,一般选择文件系统,地址为本机的本地地址。语言为.NET网站中使用的语言,如果选择Visual C#,则默认的开发语言为C#,否则为Visual Basic。创建了ASP...
  • 6.2 手机策划的一般步骤 92 6.3 手机游戏策划书模板 94 6.4 手机游戏策划的特点及与普通游戏策划的区别 95 6.5 手机游戏美工 95 6.6 手机游戏项目开发流程介绍 95 6.6.1 第一阶段:提案 96 6.6.2 第二阶段:...
  • 7.4 DirectDraw开发的步骤 7.5 小结 第八章 组件对象模型(COM) 8.1 概述 8.2 COM接口 8.3 IDL语言 8.4 CoClass和Class Factory 8.5 COM扩展 8.5.1 ActiveX控件(ActiveX Control) 8.5.2 ActiveX文档(ActiveX ...
  • ASP.NET精品课程+源代码

    千次下载 热门讨论 2009-01-05 20:15:51
    8 数据列表控件应用 16 8 8 9 网络论坛设计实例 6 6 合 计 108 52 56 (1) 每次课堂教学2学时时间分配 步骤 教学内容 时间分配 告之 本讲内容、回顾上讲内容、知识点、学习目标 5 引入 案例分析各知识点学习 10 ...
  • 前文已经介绍了ListView和RecyclerView等各种列表控件,在实际的开发中,会经常遇到大批量数据加载和展示问题,本节课来具体学习一下常见方式和步骤。 一、json解析 移动端和服务器交互一般用得较多数据...

    前文已经介绍了ListView和RecyclerView等各种列表控件,在实际的开发中,会经常遇到大批量的数据加载和展示的问题,本节课来具体的学习一下常见的方式和步骤。

    一、json解析

    移动端和服务器交互一般用得较多的数据传递方式都是 Json 字符串的形式, 保存对象,我们也可以写成一个 Json 字符串然后存储。

    常见的解析 Json的方式有Android自带Json解析器, Gson,Fastjson,jackson 等。

    1.0 http://Json.cn工具

    通过一个在线网站工具可以实时的实现json数据的格式化:http://www.json.cn/

    1.1 Android自带的Json解析器

    自带的解析器的API都存在于org.json包下,用到的类有下面这些:

    • JSONObject: Json对象,可以完成Json字符串与Java对象的相互转换
    • JSONArray: Json数组,可以完成Json字符串与Java集合或对象的相互转换,[]
    • JSONStringer: Json文本构建类,这个类可以帮助快速和便捷的创建JSON text, 每个JSONStringer实体只能对应创建一个JSON text
    • JSONTokener:Json解析类
    • JSONException:Json异常

    使用方法参见案例17的原生解析方法,如下:

    private List<Lesson> parseJsonByNative(String jsonStr) {
      List<Lesson> lessons = new ArrayList<>();
      try {
        JSONObject jsonObject = new JSONObject(jsonStr);
        int code = jsonObject.getInt("status");
        if (code != 1) {
          return null;
        }
        JSONArray dataArray = jsonObject.getJSONArray("data");
        for (int i = 0; i < dataArray.length(); i++) {
          JSONObject lessonObject = dataArray.getJSONObject(i);
          int id = lessonObject.getInt("id");
          String name = lessonObject.getString("name");
          String picSmall = lessonObject.getString("picSmall");
          String picBig = lessonObject.getString("picBig");
          String description = lessonObject.getString("description");
          int learner = lessonObject.getInt("learner");
    ​
          Lesson lesson = new Lesson();
          lesson.setId(id);
          lesson.setName(name);
          lesson.setPicSmall(picSmall);
          lesson.setPicBig(picBig);
          lesson.setDescription(description);
          lesson.setLearner(learner);
    ​
          lessons.add(lesson);
        }
      } catch (JSONException e) {
        e.printStackTrace();
      }
      return lessons;
    }

    1.2 Gson解析库

    Gson是google开源的一款用于json解析的库,受到很多开发者的喜爱。

    Gson在github的开源库地址:https://github.com/google/gson

    在Android中使用gson有两种方式:

    • 在build.gradle文件中设置库依赖:implementation 'com.google.code.gson:gson:2.8.6'
    • 下载gson.jar包,放在Android项目恶libs目录中

    设置依赖后,即可在项目中使用Gson解析数据,如下所示:

    private Lesson[] parseByGson(String jsonStr) {
      Gson gson = new Gson();
      Type type = new TypeToken<Common<Lesson>>() {
      }.getType();
      Common<Lesson> common = gson.fromJson(jsonStr, type);
      return common.data;
    }

    1.3 FastJson解析库

    fastjson是阿里巴巴团队开源的一款json解析库,使用的项目和团队也很多。在github上的star数达到了21.2k,超过了gson。

    FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。

    fastjson开源库在github的开源地址:https://github.com/alibaba/fastjson

    在Android中使用fastjson,需要在项目的build.gradle文件中设置依赖:

    compile 'com.alibaba:fastjson:1.1.71.android'

    同样的和gson一样,也可以下载最新的jar文件,放在android项目的libs目录中进行依赖设置。

    public static List<Lesson> parseByFastJson(String jsonStr) {
      com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsonStr);
      com.alibaba.fastjson.JSONArray jsonArray = jsonObject.getJSONArray("data");
      return  jsonArray.toJavaList(Lesson.class);
    }

    1.4 Jackson

    Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson是最流行的json解析器之一,Java应用框架中很多都是使用Jackson库。目前github上Jackson的star数量达到5.5K。

    Jackson在github上的地址如下:https://github.com/FasterXML/jackson

    使用Jackson:

    • 先下载jar包
    • 放入到项目的libs目录中,设置依赖为library
    • 在x项目中进行使用

    此处省略案例,可自行练习。

    1.5 解析库对比和总结

    • 反序列化操作:总体上JSONObject处理性能比较突出,但是JSONObject的缺点是啰嗦,代码量多,需要些try...catch等冗余代码。
    • Gson:随着数据量的增大,Gson库耗时会增加。
    • FastJson操作:性能比较好,数据的量级对内存消耗影响较小,且消耗内存比较小。
    • JSONObject原生:数据量大时,JSONObject内存消耗很明显。
    • Jackson:耗时和内存消耗上都较大。

    ① 数据量小时,可以选择JSONObject进行处理,要接收代码量冗余。Gson和FastJson差不多。

    ② 数据量大时,或者数据量会有明显的量级的增加变化,FastJson综合表现更好。

    二、加载网络数据的注意事项

    json数据通常都是通过网络接口请求而来,因此需要进行网络访问获取数据,包括图片的加载也是需要网络的。

    uses-permission网络权限

    使用网络,需要在AndroidMainfest.xml文件中设置使用网络权限。

    <!--网络权限-->
    <uses-permission android:name="android.permission.INTERNET"/>

    Https规范

    在Android P版本开始,为了安全起见,不在允许使用http形式的接口。为了解决这个问题,可以通过在AndroidManifest.xml文件的Application文件中,设施usesCleartextTraffic属性为true来,表示使用明文网络流量。推荐还是尽快转换接口升级为https。

    数据请求更新规范

    ① 在Android中,不能在主线程请求网络,否则会报错,网络请求需要放在工作子线程中。

    ② 在Android中,请求数据完毕,不能在子线程中操作UI,否则会报错。

    图片加载开源库

    图片加载在android中可以使用比较成熟的开源库来解决,常用的图片加载开源库是Glide,picasso等。

    glide

    glide在github上的开源地址是:https://github.com/bumptech/glide

    使用时首先需要引入glide库的依赖:

    //图片网络库
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

    在图片控件加载的地方,执行如下操作:

     Glide.with(mContext).load(lesson.getPicBig()).into(holder.imgCover);

    picasso

    picasso在github上的开源地址是:https://github.com/square/picasso

    使用时首先需要引入glide库的依赖:

    implementation 'com.squareup.picasso:picasso:2.71828'

    在图片控件加载的地方,执行如下操作:

    Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);

    三、Android常见的网络请求

    3.1 HttpURLConnection

    与java的基础相同,HttpURLConnection可以实现网络请求。具备步骤为:

    • 构建URL。
    • openConnection打开HttpURLConnection对象。
    • 通过IO流读取数据。

    3.2 Volley库

    在Goole I/O 2013上发布的网络通信库,取名为Volley。

    Volley的优势及特点是:自动调度网络请求、支持请求优先级、支持取消请求,可以取消单个请求或多个,并且Volley回调时候是在主线程,可以直接操作UI。

    Volley库的操作和使用说明文档,可以访问如下地址:https://developer.android.com/training/volley/index.html

    设置库依赖

    implementation 'com.android.volley:volley:1.1.1'

    RequestQueue请求列队

    请求之前,首先需要构建RequestQueue请求列队,全局也只初始化一次就好。

    Request请求对象

    Request请求对象,有StringRequest、ImageRequest、ClearCacheRequest、JsonRequest这四个子类。

    可以给Request设置一个tag,并通过RequestQueue.cancelAll(tag)可以进行取消。

    3.3 Okhttp

    第二种方式是使用成熟的网络请求库,比如说Okhttp,非常火的一个网络库,由Square公司提供。

    Okhttp开源库的github地址如下:https://github.com/square/okhttp

    最新的Okhttp库的版本是4.6.0,在Android应用中使用该库的操作方法是设置库依赖,在build.gradle文件中:

    implementation("com.squareup.okhttp3:okhttp:4.6.0")

    3.3.1 使用步骤

    • 构建OkHttpClient对象:全局只需要初始化一次即可。
    • Request对象:通过Builder进行构建和参数设置。
    • 请求:get请求直接使用.get();post请求通过.post(RequestBody),携带数据。
    OkHttpClient client = new OkHttpClient();
    
    String run(String url) throws IOException {
      Request request = new Request.Builder()
          .url(url)
          .build();
      try (Response response = client.newCall(request).execute()) {
        return response.body().string();
      }
    }

    OkHttp库的请求,回调方法是运行在子线程中,因此不能直接在回调函数更新ui操作,如果在子线程中操作UI,刷新界面操作,会报如下错误:

    Only the original thread that created a view hierarchy can touch its views

    如果出现该错误,可以使用如下的方法解决。该方法用于回到主线程操作UI:

    ...
    final String jsonStr = response.body().string();
    runOnUiThread(new Runnable() {
      @Override
      public void run() {
        DialogUtils.closeDialog(mDialog);
        mData = Data.parseByFastJson(jsonStr);
        setDataAndAdapter();
      }
    });
    ...
    展开全文
  • 一个好用数据库类

    2008-05-14 08:36:06
    然后通过ODBC把这些文本文件映射成表,这些文件的目录就成为一个数据库,这些我们就可以很方便的对这些文件的内容通过sql来操作查询,这样开发的效率会高一些,而且是在本地,速度完全可以满足。

空空如也

空空如也

1 2 3 4 5 6
收藏数 112
精华内容 44
关键字:

列表控件开发的一般步骤