美文网首页
一个iOS开发者的android修行之路二:UITableVie

一个iOS开发者的android修行之路二:UITableVie

作者: XcqRomance | 来源:发表于2017-11-28 16:24 被阅读170次

    尽管现在主流的移动设备的屏幕尺寸都越来越大,特别是iPhone X的出现,以后的趋势都是全屏手机,但是一屏的显示的内容还是有限的,当我们需要有大量数据需要展示时就可以使用这两个控件。这两个控件的相同点都是允许用户上下滑动,以便展示屏幕区域外的内容。很多主流的应用,比如微信、QQ的消息列表,微信朋友圈,微博等等应用的很多界面都是使用这两个控件实现的。

    一、UITableView的基本使用

    1. iOS添加一个UITableView有两种方式。一是:纯代码初始化一个UITableView;二是在storyboard中直接拖入一个UITableView并且设置约束添加,同时设置tableView的dataSource和delegate为ViewController。这两种方式并没有优劣之分,使用第二种方式是苹果推荐的快速开发的方式。我的事例代码选择的第二种方法。
      在storyboard添加UITableView的四步曲
    2. 自定义UITableViewCell,勾选同时勾选xib,我这里命名为TestTableViewCell,里面添加两个控件ImageView和Label,同时设置应用。同时设置xib中的重用identifier为:TestTableViewCell
    3. 注册重用的cell,在ViewControllerviewDidLoad方法中注册自定义cell。
    let nib = UINib(nibName: "TestTableViewCell", bundle: nil)
    tableView.register(nib, forCellReuseIdentifier: "TestTableViewCell")
    
    1. 配置tableView显示的数据源,实际项目中为网络请求的数据,demo中为模拟了100条假数据。
    2. 实现tableView的数据源和代理方法。
      其中这两个数据源方法必须实现:func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Intfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell,否则会app会闪退。其中第一个方法用来指明cell的个数,第二个方法用来设置cell的数据,demo中的设置UIImageView和UILabel。
      cell点击事件的响应,则需要实现代理方法func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
      下面是整个ViewController代码:
    //
    //  ViewController.swift
    //  iOSTableViewDemo
    //
    //  Created by romance on 2017/11/28.
    //  Copyright © 2017年 firstleap. All rights reserved.
    //
    
    import UIKit
    
    final class ViewController: UIViewController {
      
      @IBOutlet weak var tableView: UITableView!
      final fileprivate var dataList = [TestModel]()
      
      override func viewDidLoad() {
        super.viewDidLoad()
        
        let nib = UINib(nibName: "TestTableViewCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "TestTableViewCell")
        setupData()
      }
      
      private func setupData() {
        for _ in 0...100 {
          let model1 = TestModel(imageName: "set_icon_about", title: "关于")
          dataList.append(model1)
          let model2 = TestModel(imageName: "set_icon_change", title: "头像")
          dataList.append(model2)
          let model3 = TestModel(imageName: "set_icon_clean", title: "清楚")
          dataList.append(model3)
          let model4 = TestModel(imageName: "set_icon_edit", title: "修改")
          dataList.append(model4)
        }
      }
      
    }
    
    extension ViewController: UITableViewDataSource, UITableViewDelegate {
      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
      }
      
      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as! TestTableViewCell
        let model = dataList[indexPath.row]
        cell.icon?.image = UIImage(named: model.imageName);
        cell.title?.text = model.title
        return cell
      }
      
      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        let model = dataList[indexPath.row]
        let showtitle = model.title
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
        label.text = showtitle
        label.textAlignment = .center
        label.backgroundColor = .lightGray
        label.center = view.center
        label.alpha = 0
        self.view.addSubview(label)
        
        UIView.animate(withDuration: 0.25, animations: {
          label.alpha = 1
        }) { (b) in
          DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2, execute: {
            UIView.animate(withDuration: 0.25, animations: {
              label.alpha = 0
            }, completion: { (b) in
              label.removeFromSuperview()
            })
          })
        }
      }
    }
    

    二、ListView的基本使用

    1. activity_main.xml中添加ListView布局,充满父容器,其实iOS中的storyboard和xib文件也是xml语言编写(也就是说和android的xml文件类似),只不过苹果公司开发Xcode可以图形化界面进行设置约束,而Android Studio尽管也可以通过拖控件进行布局,但是一般都不使用。
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </LinearLayout>
    
    1. 设置ListView子项布局test_item.xml。
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <ImageView
            android:id="@+id/test_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/set_icon_about"/>
    
        <TextView
            android:id="@+id/test_tile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:text="hehe"
            android:textSize="21sp"
            android:layout_marginLeft="8dp"/>
    
    </LinearLayout>
    
    1. 自定义ListView的适配器TestAdapter
    public class TestAdapter extends ArrayAdapter {
    
        private int resourceID;
    
        public TestAdapter(@NonNull Context context, int resource, List<TestModel> objects) {
            super(context, resource,objects);
            resourceID = resource;
        }
    
        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            TestModel testModel = (TestModel)getItem(position);
            View view;
            ViewHolder viewHolder;
            if (convertView == null) {
                view = LayoutInflater.from(getContext()).inflate(resourceID, parent, false);
                viewHolder = new ViewHolder(view);
                view.setTag(viewHolder);
            } else {
                view = convertView;
                viewHolder = (ViewHolder)view.getTag();
            }
            viewHolder.imageView.setImageResource(testModel.getImageID());
            viewHolder.textView.setText(testModel.getTitle());
            return view;
        }
    
        class ViewHolder {
            ImageView imageView;
            TextView textView;
            ViewHolder(View view ) {
                imageView = (ImageView)view.findViewById(R.id.test_image);
                textView = (TextView)view.findViewById(R.id.test_tile);
            }
        }
    
    }
    
    
    1. 添加Adapter数据,同iOS类似,demo添加了100条假数据。
    2. onCreate方法中创建一个TestAdapter对象adapter,并且设置为listView的适配器。为ListViewitem子项添加点击事件。
      MainActivity的代码如下:
    public class MainActivity extends AppCompatActivity {
        private List<TestModel> dataList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initsData();
            TestAdapter adapter = new TestAdapter(MainActivity.this,R.layout.test_item,dataList);
            ListView listView = (ListView)findViewById(R.id.list_view);
            listView.setAdapter(adapter);
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    TestModel model = dataList.get(i);
                    Toast.makeText(MainActivity.this,model.getTitle(),Toast.LENGTH_SHORT).show();
                }
            });
        }
    
        private void initsData() {
            for (int i = 0; i < 100; i ++) {
                TestModel testModel = new TestModel(R.drawable.set_icon_about,"关于");
                dataList.add(testModel);
                TestModel testModel2 = new TestModel(R.drawable.set_icon_change,"头像");
                dataList.add(testModel2);
                TestModel testModel3 = new TestModel(R.drawable.set_icon_clean,"清楚");
                dataList.add(testModel3);
                TestModel testModel4 = new TestModel(R.drawable.set_icon_edit,"修改");
                dataList.add(testModel4);
            }
        }
    }
    

    三、UITableView和ListView的对比

    相同点:

    1. 都有重用机制,来提高滑动性能;
    2. 见文章开头所写;

    不同点:

    1. UITableView继承自UIScrollView是一个滑动的View,而ListView则不是集成ScrollView。(或许这两点并没有没有可比性,毕竟是两个不同框架提供的库)
    2. UITableView有两种样式,group和plain。而ListView只有一种类似于iOS的plain模式,
      group样式
      plain样式

    最后,文中使用的控件对比:
    iOS图片显示控件UIImageView与Android的ImageView控件对应,文本显示控件iOS是UILabel,对应Android的TextView。
    GitHub demo地址

    相关文章

      网友评论

          本文标题:一个iOS开发者的android修行之路二:UITableVie

          本文链接:https://www.haomeiwen.com/subject/blesbxtx.html