Skip to content

Latest commit

 

History

History
175 lines (111 loc) · 7.48 KB

ListView控件以及它背后的故事.md

File metadata and controls

175 lines (111 loc) · 7.48 KB

##ListView控件以及它背后的故事

为什么会突然介绍控件呢?

  • 因为它是View,能给人带来最直观的效果,学习的过程是有点无聊的,但是能一边做一边看到有意思的效果,那不是蛮有趣的嘛!

好的,那什么是ListView呢?

官方的解释: ListView is a view group that displays a list of scrollable(可滚动的) items. The list items are automatically(自动的) inserted to the list using an Adapter that pulls content from a source such as an array or database query and converts each item result into a view that's placed into the list.

解释一下:ListView这个控件就是用于显示列表数据,举个栗子:Alt text

为什么先介绍这个控件呢?因为很重要,又很好玩,大多数常见的app都会使用ListView这个控件来显示数据,我们常用的QQ、人人、G+等等


ListView 的有趣属性

android:scrollbarStyle属性及滚动条和分割线覆盖问题 本文主要介绍android viewandroid:scrollbarStyle属性意义 android:scrollbarStyle可以定义滚动条的样式和位置,可选值有insideOverlayinsideInsetoutsideOverlayoutsideInset四种。 其中insideoutside分别表示是否在viewpadding区域内,overlayinset表示覆盖在view上或是插在view后面,所以四种值分别表示: 1.insideOverlay:默认值,表示在padding区域内并且覆盖在view上 2.insideInset:表示在padding区域内并且插入在view后面 3.outsideOverlay:表示在padding区域外并且覆盖在view上,推荐这个 4.outsideInset:表示在padding区域外并且插入在view后面

Alt text

来讲讲ListView工作原理吧。ListView控件背后的Pattern(模式),著名的MVC。说白了,ListView在装载数据时并不是用ListView.add()的方法添加数据,而是需要一个Adapter对象。其实这么做也是可以的,但是却没有采取这样的做法,因为维护的成本太高

来看看他们三个的关系


Model - 数据模型层,也就是List<Person> View - 视图层,也就是ListView Controller -控制层,也就是Adapter

Alt text

来聊聊MVC的好处

  • 逻辑和界面分离
  • 需求在不断修改,加强代码可维护性

拓展话题

Observer Pattern (观察者模式) 你是如何认识报纸和杂志的订阅的? 1.报社的任务,出版报纸 2.向某家报社订阅报纸,只要他们有新报纸出版,就会给你送过来。你要你是他们的订户,就会一直收到报纸。 3.当你不想看报纸的时候,取消订阅,他们就不送了。 4.只要报社还在运营,就一定会有人向他们定报纸或者取消订报纸。

对,就是这么回事。当你意识到报纸的订阅是怎么回事的时候,你也就知道观察者模式是怎么回事了。名字有所不同,报社改称为“主题”(Subject),订阅者改称为“观察者”。

好的,最后我再附上一些Android 入门的视频链接吧 罗升阳老师的android之旅 张泽华老师的android之旅 很好的一篇总结

通过Loader

Using a CursorLoader is the standard way(标准的方法) to query a Cursor as an asynchronous task(异步任务) in order to avoid blocking your app's main thread with the query. When the CursorLoader receives the Cursor result, the LoaderCallbacks receives a callback to onLoadFinished(), which is where you update your Adapter(更新你的adapter) with the new Cursor and the list view then displays the results.

Although the CursorLoader APIs were first introduced in Android 3.0 (API level 11), they are also available in the Support Library so that your app may use them while supporting devices running Android 1.6 or higher.

举个栗子

The following example uses ListActivity, which is an activity that includes a ListView as its only layout element by default. It performs a query to the Contacts Provider for a list of names and phone numbers.

The activity implements the LoaderCallbacks interface in order to use a CursorLoader that dynamically loads the data for the list view.

public class ListViewLoader extends ListActivity
        implements LoaderManager.LoaderCallbacks<Cursor> {

    // This is the Adapter being used to display the list's data
    SimpleCursorAdapter mAdapter;

    // These are the Contacts rows that we will retrieve
    static final String[] PROJECTION = new String[] {ContactsContract.Data._ID,
            ContactsContract.Data.DISPLAY_NAME};

    // This is the select criteria
    static final String SELECTION = "((" + 
            ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" +
            ContactsContract.Data.DISPLAY_NAME + " != '' ))";

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

        // Create a progress bar to display while the list loads
        ProgressBar progressBar = new ProgressBar(this);
        progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, Gravity.CENTER));
        progressBar.setIndeterminate(true);
        getListView().setEmptyView(progressBar);

        // Must add the progress bar to the root of the layout
        ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
        root.addView(progressBar);

        // For the cursor adapter, specify which columns go into which views
        String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
        int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1

        // Create an empty adapter we will use to display the loaded data.
        // We pass null for the cursor, then update it in onLoadFinished()
        mAdapter = new SimpleCursorAdapter(this, 
                android.R.layout.simple_list_item_1, null,
                fromColumns, toViews, 0);
        setListAdapter(mAdapter);

        // Prepare the loader.  Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
    }

    // Called when a new Loader needs to be created
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
                PROJECTION, SELECTION, null, null);
    }

    // Called when a previously created loader has finished loading
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Swap the new cursor in.  (The framework will take care of closing the
        // old cursor once we return.)
        mAdapter.swapCursor(data);
    }

    // Called when a previously created loader is reset, making the data unavailable
    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
        mAdapter.swapCursor(null);
    }

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Do something when a list item is clicked
    }
}