【android】ListView 的 stackFromBottom 选项

来源:互联网 发布:孟德尔 知乎 编辑:程序博客网 时间:2024/04/29 22:43

## 目录 ##

  • 操作系统
  • 导读
  • 调用方法
  • 布局文件设置
  • 源码分析
  • 实例

操作环境

  • 操作系统: win7-64bit 旗舰版
  • android 版本: android-23
  • 模拟器:海马玩模拟器 0.9.0 Beta( android 4.2.2 )

导读

默认情况下,ListView 是从上到下逐条显示 item 的;但我们可以根据实际需要,让其按照从下到上的方式显示。

调用方法

ListView.java

  • 用于检测当前的状态是否为 从下到上 的方式
public boolean isStackFromBottom()
  • 用于设置 ListView 中 item 顺序的显示方式( 设置后会立刻刷新 ListView 的显示 )
public void setStackFromBottom(boolean stackFromBottom)

布局文件设置

    <ListView android:id="@+id/lv_test"        android:layout_width="match_parent"        android:layout_height="300dp"        <!-- 以下只能选择一项 -->        android:stackFromBottom="true"        android:stackFromBottom="false"        >    </ListView>

源码分析

分析内容主要为:boolean 值对于 Item 布局顺序的影响

  • 设置状态:其中修改了 mStackFromBottom 的值;
/**     * When stack from bottom is set to true, the list fills its content starting from     * the bottom of the view.     *     * @param stackFromBottom true to pin the view's content to the bottom edge,     *        false to pin the view's content to the top edge     */    public void setStackFromBottom(boolean stackFromBottom) {        if (mStackFromBottom != stackFromBottom) {            mStackFromBottom = stackFromBottom;            requestLayoutIfNecessary();        }    }
  • adapter 对应的数据集内容有更改的时候会检测 mStackFromBottom 的值,并设置对应的 mLayout 状态
@Overrideprotected void handleDataChanged() {    ... 省略 ...    mLayoutMode = mStackFromBottom ? LAYOUT_FORCE_BOTTOM : LAYOUT_FORCE_TOP;    ... 省略 ...}
  • ListView 在刷新布局时会根据 mLayoutMode 状态来实现具体的 Item 显示顺序
@Overrideprotected void layoutChildren() {    ... 省略 ...            case LAYOUT_FORCE_BOTTOM:                sel = fillUp(mItemCount - 1, childrenBottom);                adjustViewsUpOrDown();                break;            case LAYOUT_FORCE_TOP:                mFirstPosition = 0;                sel = fillFromTop(childrenTop);                adjustViewsUpOrDown();                break;    ... 省略 ...}
  • 下面就看个从上到下显示的吧:
/**     * Fills the list from top to bottom, starting with mFirstPosition     *     * @param nextTop The location where the top of the first item should be     *        drawn     *     * @return The view that is currently selected     */    private View fillFromTop(int nextTop) {        mFirstPosition = Math.min(mFirstPosition, mSelectedPosition);        mFirstPosition = Math.min(mFirstPosition, mItemCount - 1);        if (mFirstPosition < 0) {            mFirstPosition = 0;        }        return fillDown(mFirstPosition, nextTop);    }
    /**     * Fills the list from pos down to the end of the list view.     *     * @param pos The first position to put in the list     *     * @param nextTop The location where the top of the item associated with pos     *        should be drawn     *     * @return The view that is currently selected, if it happens to be in the     *         range that we draw.     */    private View fillDown(int pos, int nextTop) {        View selectedView = null;        int end = (mBottom - mTop);        if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {            end -= mListPadding.bottom;        }        while (nextTop < end && pos < mItemCount) {            // is this the selected item?            boolean selected = pos == mSelectedPosition;            View child = makeAndAddView(pos, nextTop, true, mListPadding.left, selected);            nextTop = child.getBottom() + mDividerHeight;            if (selected) {                selectedView = child;            }            pos++;        }        setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1);        return selectedView;    }

实例

  • test_list_view.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"     android:layout_width="match_parent"    android:layout_height="match_parent">    <ListView android:id="@+id/lv_test"        android:layout_width="match_parent"        android:layout_height="300dp">    </ListView>    <Button android:id="@+id/btn_add_item"        android:layout_width="match_parent"        android:layout_height="40dp"        android:text="增加新 item"        />    <Button android:id="@+id/btn_set_true"        android:layout_width="match_parent"        android:layout_height="40dp"        android:text="设置为 true"        />    <Button android:id="@+id/btn_set_false"        android:layout_width="match_parent"        android:layout_height="40dp"        android:text="设置为 false"        /></LinearLayout>
  • MainActivity.java:
public class MainActivity extends Activity {    ArrayList<String> mItemStrArr = new ArrayList<>();    ArrayAdapter mAdapter;    int i = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.test_list_view);        this.testListViewStackFromBottom();    }    void testListViewStackFromBottom(){        Button btnAddItem = (Button) this.findViewById(R.id.btn_add_item);        Button btnSetTrue = (Button) this.findViewById(R.id.btn_set_true);        Button btnSetFalse = (Button) this.findViewById(R.id.btn_set_false);        ListView lv = (ListView)this.findViewById(R.id.lv_test);        // 实例化对象        mAdapter = new ArrayAdapter(this, R.layout.test_item, R.id.tv_content, mItemStrArr);        // 设置适配器        lv.setAdapter(mAdapter);        btnAddItem.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mItemStrArr.add("item_" + i++);                mAdapter.notifyDataSetChanged();            }        });        // 设置监听        btnSetTrue.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                ListView lv = (ListView)MainActivity.this.findViewById(R.id.lv_test);                lv.setStackFromBottom(true);            }        });        btnSetFalse.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                ListView lv = (ListView)MainActivity.this.findViewById(R.id.lv_test);                lv.setStackFromBottom(false);            }        });    }
  • 效果图:
    这里写图片描述
0 0
原创粉丝点击