layout_layoutparams方法 - CSDN
  • 关于Layout的总结。

    2018-07-14 08:42:05
    1.关于coordinatorLayoutCoordinatorLayout简介CoordinatorLayout是在 Google IO/15 大会发布的,遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的...

    CoordinatorLayout简介

    CoordinatorLayout是在 Google IO/15 大会发布的,遵循Material 风格,包含在 support Library中,结合AppbarLayout, CollapsingToolbarLayout等 可 产生各种炫酷的效果


    简单来说就是

    • 作为最上层的View
    • 作为一个 容器与一个或者多个子View进行交互
    与AppbarLayout组合的滚动布局(RecyclerView, NestedScrollView等),需要设置 app:layout_behavior = "@string/appbar_scrolling_view_behavior" .没有设置的话, AppbarLayout将不会响应滚动布局的滚动事件.

    类型说明
    int SCROLL_FLAG_ENTER_ALWAYSWhen entering (scrolling on screen) the view will scroll on any downwards scroll event, regardless of whether the scrolling view is also scrolling.
    int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSEDAn additional flag for 'enterAlways' which modifies the returning view to only initially scroll back to it's collapsed height.
    int SCROLL_FLAG_EXIT_UNTIL_COLLAPSEDWhen exiting (scrolling off screen) the view will be scrolled until it is 'collapsed'.
    int SCROLL_FLAG_SCROLLThe view will be scroll in direct relation to scroll events.
    int SCROLL_FLAG_SNAPUpon a scroll ending, if the view is only partially visible then it will be snapped and scrolled to it's closest edge.
    类型说明
    int SCROLL_FLAG_ENTER_ALWAYSW((entering) / (scrolling on screen))下拉的时候,这个View也会跟着滑出。
    int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED另一种enterAlways,但是只显示折叠后的高度。
    int SCROLL_FLAG_EXIT_UNTIL_COLLAPSED((exiting) / (scrolling off screen))上拉的时候,这个View会跟着滑动直到折叠。
    int SCROLL_FLAG_SCROLL这个View将会响应Scroll事件
    int SCROLL_FLAG_SNAP在Scroll滑动事件结束以前 ,如果这个View部分可见,那么这个View会停在最接近当前View的位置

    我们可以通过两种 方法设置这个Flag

    • 方法一
     setScrollFlags(int) 
    
    • 方法二
     app:layout_scrollFlags="scroll|enterAlways"
    

    注意事项

    AppBarLayout必须作为CoordinatorLayout的直接子View,否则它的大部分功能将不会生效,如layout_scrollFlags等。


    CollapsingToolbarLayout

    CollapsingToolbarLayout继承与FrameLayout,官网地址,请自备梯子。

    简单来说 ,CollapsingToolbarLayout是工具栏的包装器,它通常作为AppBarLayout的孩子。主要实现以下功能

    • Collapsing title(可以折叠 的 标题 )
    • Content scrim(内容装饰),当我们滑动的位置 到达一定阀值的时候,内容 装饰将会被显示或者隐藏
    • Status bar scrim(状态栏布)
    • Parallax scrolling children,滑动的时候孩子呈现视觉特差效果
    • Pinned position children,固定位置的 孩子

    下面我们一起来看一下几个常量

    常量解释说明
    int COLLAPSE_MODE_OFFThe view will act as normal with no collapsing behavior.(这个 View将会 呈现正常的结果,不会表现出折叠效果)
    int COLLAPSE_MODE_PARALLAXThe view will scroll in a parallax fashion. See setParallaxMultiplier(float) to change the multiplier used.(在滑动的时候这个View 会呈现 出 视觉特差效果 )
    int COLLAPSE_MODE_PINThe view will pin in place until it reaches the bottom of the CollapsingToolbarLayout.(当这个View到达 CollapsingToolbarLayout的底部的时候,这个View 将会被放置,即代替整个CollapsingToolbarLayout)

    我们有两种方法可以设置这个常量,

    方法一:在代码中使用这个方法

    setCollapseMode(int collapseMode)
    

    方法 二:在布局文件中使用自定义属性

    app:layout_collapseMode="pin"
    

    DrawerLayout 简单使用

    介绍

    drawerLayout是Support Library包中实现了侧滑菜单效果的控件,可以说drawerLayout是因为第三方控件如MenuDrawer等的出现之后,google借鉴而出现的产物。drawerLayout分为侧边菜单和主内容区两部分,侧边菜单可以根据手势展开与隐藏(drawerLayout自身特性),主内容区的内容可以随着菜单的点击而变化(这需要使用者自己实现)。

    实用

    DrawerLayout 实用比较简单,这里只介绍简单使用和常用API。

    1. 在布局文件中使用DrawerLayout 进行设置。如下示例代码:
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/dlyt_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
        <!-- 内容 -->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <Button
                android:id="@+id/btn_context"
                android:text="context"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    
        </FrameLayout>
    
        <!-- 左边菜单 -->
        <FrameLayout
            android:background="@color/colorAccent"
            android:layout_gravity="start"
            android:layout_width="200dp"
            android:layout_height="match_parent">
            <Button
                android:id="@+id/btn_left_menu"
                android:text="left menu"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </FrameLayout>
    
        <!-- 右边菜单 -->
        <FrameLayout
            android:background="@color/colorAccent"
            android:layout_gravity="end"
            android:layout_width="200dp"
            android:layout_height="match_parent">
            <Button
                android:id="@+id/btn_right_menu"
                android:text="right menu"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </FrameLayout>
    </android.support.v4.widget.DrawerLayout>
    
    

    在 DrawerLayout 布局中有三个元素,

    1. view 主体
    2. 左边菜单:
      左边菜单的设定使用android:layout_gravity="start" 设置。
    3. 右边菜单:
      右边菜单的设定使用android:layout_gravity="end" 设置。

    通过上面,我们就已经实现了左右划出菜单效果。
    如果我们需要加上一些控制逻辑,可能就需要一些的一些API了。

    DrawerLayout 中部分 API 介绍

    1. isDrawerOpen(@EdgeGravity int drawerGravity) : 判断菜单是否打开。

    传入参数:

    • GravityCompat.START : 左边菜单是否打开。
    • GravityCompat.END : 右边菜单是否打开。

    返回值

    • 打开 : true
    • 关闭 : false
    1. openDrawer(@EdgeGravity int gravity) : 打开菜单

    传入参数:

    • GravityCompat.START : 打开左边菜单。
    • GravityCompat.END : 打开右边菜单。
    1. closeDrawer(@EdgeGravity int gravity) : 关闭菜单

    传入参数:

    • GravityCompat.START : 关闭左边菜单。
    • GravityCompat.END : 关闭右边菜单。
    1. addDrawerListener(@NonNull DrawerListener listener) : 添加监听
    2. DrawerListener 类
    • onDrawerSlide(View drawerView, float slideOffset) : 滑动时调用
    • onDrawerOpened(View drawerView) : 打开菜单时调用
    • onDrawerClosed(View drawerView) : 关闭菜单时调用
    • onDrawerStateChanged(@State int newState) : 菜单状态改变时调用

    其他API查看源码就会明白如何使用。

    如下Java示例代码:

    //添加监听
    DrawerLayout.addDrawerListener(new DrawerViewListener());
    
    private class DrawerViewListener implements DrawerLayout.DrawerListener {
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
        //滑动时调用
        }
    
        @Override
        public void onDrawerOpened(View drawerView) {
        //打开菜单时调用
        }
    
        @Override
        public void onDrawerClosed(View drawerView) {
        //关闭菜单时调用
        }
    
        @Override
        public void onDrawerStateChanged(int newState) {
        //菜单状态改变时调用
        }
    }
    

    AutoCompleteTextView

    AutoCompleteTextView常用属性

    属性描述
    android:completionHint设置出现在下拉菜单底部的提示信息
    android:completionThreshold设置触发补全提示信息的字符个数
    android:dropDownHorizontalOffset设置下拉菜单于文本框之间的水平偏移量
    android:dropDownHeight设置下拉菜单的高度
    android:dropDownWidth设置下拉菜单的宽度
    android:singleLine设置单行显示文本内容
    android:dropDownVerticalOffset设置下拉菜单于文本框之间的垂直偏移量

    使用ArrayAdapter来作为AutoCompleteTextView的数据适配器

    • 简单的xml布局
    <AutoCompleteTextView
        android:id="@+id/tv_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/hint_type"
        android:completionHint="@string/chint_recent"
        android:completionThreshold="1" />
    
    • 默认AutoCompleteTextView中的数据保存在SharedPreferences中,故将SharedPreferences做了简单的API封装以方便数据存取,详细的SharedPreferences请参考这里:SharedPreferences
    // 从SharedPreferences中获取历史记录数据
    private String getHistoryFromSharedPreferences(String key) {
        SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE);
        return sp.getString(key, SP_EMPTY_TAG);
    }
    
    // 将历史记录数据保存到SharedPreferences中
    private void saveHistoryToSharedPreferences(String key, String history) {
        SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, history);
        editor.apply();
    }
    
    // 清除保存在SharedPreferences中的历史记录数据
    private void clearHistoryInSharedPreferences() {
        SharedPreferences sp = getSharedPreferences(SP_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.apply();
    }
    
    • 使用默认适配器的AutoCompleteTextView相关初始化
    private void initSearchView() {
        mSearchTv = (AutoCompleteTextView) findViewById(R.id.tv_search);
        String[] mSearchHistoryArray = getHistoryArray(SP_KEY_SEARCH);
        mSearchAdapter = new ArrayAdapter<>(
                this,
                android.R.layout.simple_dropdown_item_1line,
                mSearchHistoryArray
        );
        mSearchTv.setAdapter(mSearchAdapter);  // 设置适配器
    
        // 设置下拉提示框的高度为200dp
        // mAutoCompleteTv.setDropDownHeight();      // 或XML中为android:dropDownHeight="200dp"
    
        // 默认当输入2个字符以上才会提示, 现在当设置输入1个字符就自动提示
        // mAutoCompleteTv.setThreshold(1);          // 或XML中为android:completionThreshold="1"
    
        // 设置下拉提示框中底部的提示
        // mAutoCompleteTv.setCompletionHint("最近的5条记录");
    
        // 设置单行输入限制
        // mAutoCompleteTv.setSingleLine(true);
    }
    
    private String[] getHistoryArray(String key) {
        String[] array = getHistoryFromSharedPreferences(key).split(SP_SEPARATOR);
        if (array.length > MAX_HISTORY_COUNT) {         // 最多只提示最近的50条历史记录
            String[] newArray = new String[MAX_HISTORY_COUNT];
            System.arraycopy(array, 0, newArray, 0, MAX_HISTORY_COUNT); // 实现数组间的内容复制
        }
        return array;
    }
    
    • 保存AutoCompleteTextView中的历史记录数据到SharedPreferences中
    private void saveSearchHistory() {
        String text = mSearchTv.getText().toString().trim();       // 获取搜索框文本信息
        if (TextUtils.isEmpty(text)) {                      // null or ""
            Toast.makeText(this, "Please type something again.", Toast.LENGTH_SHORT).show();
            return;
        }
    
        String old_text = getHistoryFromSharedPreferences(SP_KEY_SEARCH);// 获取SP中保存的历史记录
        StringBuilder sb;
        if (SP_EMPTY_TAG.equals(old_text)) {
            sb = new StringBuilder();
        } else {
            sb = new StringBuilder(old_text);
        }
        sb.append(text + SP_SEPARATOR);      // 使用逗号来分隔每条历史记录
    
        // 判断搜索内容是否已存在于历史文件中,已存在则不再添加
        if (!old_text.contains(text + SP_SEPARATOR)) {
            saveHistoryToSharedPreferences(SP_KEY_SEARCH, sb.toString());  // 实时保存历史记录
            mSearchAdapter.add(text);        // 实时更新下拉提示框中的历史记录
            Toast.makeText(this, "Search saved: " + text, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Search existed: " + text, Toast.LENGTH_SHORT).show();
        }
    }
    

    上面代码中,为了能够实时更新下拉提示框中的历史记录,需要在保存数据后再调用ArrayAdapter.add()方法,而不是调用ArrayAdapter.notifyDataSetChanged()

    • 实时清除下拉提示框中的历史记录
    clearHistoryInSharedPreferences();          // 试试清除历史记录
    mSearchAdapter.clear();                     // 实时清除下拉提示框中的历史记录
    
    • 效果演示
    arrayadapter_autocomplete_textview_320x512.gif

    使用自定义AutoCompleteAdapter来作为AutoCompleteTextView的数据适配器

    • 简单的xml布局

    使用RelativeLayout来容纳AutoCompleteTextView和ImageView,其中ImageView位于右侧,用于点击清除AutoCompleteTextView的内容

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center_vertical">
    
        <AutoCompleteTextView
            android:id="@+id/tv_custom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingStart="12dp"
            android:paddingEnd="40dp"
            android:hint="@string/hint_type"/>
    
        <ImageView
            android:id="@+id/iv_custom"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_marginEnd="10dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:scaleType="fitCenter"
            android:src="@drawable/ic_action_name"
            android:contentDescription="@null"/>
    </RelativeLayout>
    
    • 使用自定义适配器的AutoCompleteTextView相关初始化
    private void initCustomView() {
        mCustomTv = (AutoCompleteTextView) findViewById(R.id.tv_custom);
        mDeleteIv = (ImageView) findViewById(R.id.iv_custom);
        mDeleteIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCustomTv.setText("");              // 清空TextView的内容
            }
        });
    
        ArrayList<String> mOriginalValues = new ArrayList<>();
        String[] mCustomHistoryArray = getHistoryArray(SP_KEY_CUSTOM);
        mOriginalValues.addAll(Arrays.asList(mCustomHistoryArray));     // String[] => ArrayList<String>
        
        mCustomAdapter = new AutoCompleteAdapter(this, mOriginalValues);
        mCustomAdapter.setDefaultMode(AutoCompleteAdapter.MODE_STARTSWITH | AutoCompleteAdapter.MODE_SPLIT);// 设置匹配模式
        mCustomAdapter.setSupportPreview(true);     // 支持使用特殊符号进行预览提示内容,默认为'@'
    
        simpleItemHeight = mCustomAdapter.getSimpleItemHeight();
        Toast.makeText(this, "simpleItemHeight: " + simpleItemHeight, Toast.LENGTH_SHORT).show(); // 103
    
        mCustomAdapter.setOnFilterResultsListener(new AutoCompleteAdapter.OnFilterResultsListener() {
            @Override
            public void onFilterResultsListener(int count) {
                curCount = count;
                if (count > MAX_ONCE_MATCHED_ITEM) {        // 限制提示框最多要显示的记录行数
                    curCount = MAX_ONCE_MATCHED_ITEM;
                }
                if (curCount != prevCount) {                // 仅当目前的数目和之前的不同才重新设置下拉框高度,避免重复设置
                    prevCount = curCount;
                    mCustomTv.setDropDownHeight(simpleItemHeight * curCount);
                }
            }
        });
    
        mCustomAdapter.setOnSimpleItemDeletedListener(new AutoCompleteAdapter.OnSimpleItemDeletedListener() {
            @Override
            public void onSimpleItemDeletedListener(String value) {
                String old_history = getHistoryFromSharedPreferences(SP_KEY_CUSTOM);    // 获取之前的记录
                String new_history = old_history.replace(value + SP_SEPARATOR, "");    // 用空字符串替换掉要删除的记录
                saveHistoryToSharedPreferences(SP_KEY_CUSTOM, new_history);             // 保存修改过的记录
            }
        });
    
        mCustomTv.setAdapter(mCustomAdapter);       //
        mCustomTv.setThreshold(1);                  //
    
        // 设置下拉时显示的提示行数 (此处不设置也可以,因为在AutoCompleteAdapter中有专门的事件监听来实时设置提示框的高度)
        // mCustomTv.setDropDownHeight(simpleItemHeight * MAX_ONCE_MATCHED_ITEM);
    }
    
    • 保存AutoCompleteTextView中的历史记录数据到SharedPreferences中
    private void saveCustomHistory() {
        String text = mCustomTv.getText().toString().trim();     // 获取搜索框信息
        if (TextUtils.isEmpty(text)) {          // null or ""
            Toast.makeText(this, "Please type something again.", Toast.LENGTH_SHORT).show();
            return;
        }
    
        String old_text = getHistoryFromSharedPreferences(SP_KEY_CUSTOM);    // 获取SP中保存的历史记录
        StringBuilder sb;
        if (SP_EMPTY_TAG.equals(old_text)) {
            sb = new StringBuilder();
        } else {
            sb = new StringBuilder(old_text);
        }
        sb.append(text + SP_SEPARATOR);      // 使用逗号来分隔每条历史记录
    
        // 判断搜索内容是否已存在于历史文件中,已存在则不再添加
        if (!old_text.contains(text + SP_SEPARATOR)) {
            saveHistoryToSharedPreferences(SP_KEY_CUSTOM, sb.toString());  // 实时保存历史记录
            mCustomAdapter.add(text);        // 实时更新下拉提示框中的历史记录
            Toast.makeText(this, "Custom saved: " + text, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Custom existed: " + text, Toast.LENGTH_SHORT).show();
        }
    }
    
    • 实时清除下拉提示框中的历史记录
    clearHistoryInSharedPreferences();      // 试试清除历史记录
    mCustomAdapter.clear();                 // 实时清除下拉提示框中的历史记录
    
    • 自定义适配器AutoCompleteAdapter

    AutoCompleteAdapter参考了ArrayAdapter的部分源代码,继承自BaseAdapter并实现Filterable接口,实现了以下功能:

    1. 实现自动补全的匹配模式的配置,有三种可选匹配模式:
    MODE_CONTAINS / MODE_STARTSWITH(default) / MODE_SPLIT
    
    1. 实现匹配成功事件的回调,用于根据匹配结果数来动态设置下拉提示框的高度
    2. 实现删除匹配结果中子项的事件回调,用于实时更新存储在SharedPreferences的历史记录数据
    3. 支持使用@字符来预览所有提示内容
    public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
    
        private static final int MODE_NONE = 0x000;                 // 0000b
        public static final int MODE_CONTAINS = 0x001;              // 0001b
        public static final int MODE_STARTSWITH = 0x002;            // 0010b
        public static final int MODE_SPLIT = 0x004;                 // 0100b
        private static final String SPLIT_SEPARATOR = "[,.\\s]+";  // 分隔符,默认为空白符、英文逗号、英文句号
        private static boolean isFound = false;   // 当MODE_STARTSWITH模式匹配成功时,不再进行MODE_SPLIT模式的匹配
        private int defaultMode = MODE_STARTSWITH;                  // 0110b
    
        private LayoutInflater inflater;
        private ArrayFilter mArrayFilter;
        private ArrayList<String> mOriginalValues;      // 所有的item
        private List<String> mObjects;                  // 过滤后的item
        private final Object mLock = new Object();      // 同步锁
        private int maxMatch = 10;                      // 最多显示的item数目,负数表示全部
        private int simpleItemHeight;                   // 单行item的高度值,故需要在XML中固定父布局的高度值
    
        private char previewChar = '@';                 // 默认字符
        private boolean isSupportPreview = false;       // 是否可以使用@符号进行预览全部提示内容
    
        public AutoCompleteAdapter(Context context, ArrayList<String> mOriginalValues) {
            this(context, mOriginalValues, -1);
        }
    
        public AutoCompleteAdapter(Context context, ArrayList<String> mOriginalValues, int maxMatch) {
            this.mOriginalValues = mOriginalValues;
            // 初始化时将其设置成mOriginalValues,避免在未进行数据保存时执行删除操作导致程序的崩溃
            this.mObjects = mOriginalValues;   
            this.maxMatch = maxMatch;
            inflater = LayoutInflater.from(context);
            initViewHeight();
        }
    
        private void initViewHeight() {
            View view = inflater.inflate(R.layout.simple_dropdown_item_1line, null);
            LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.layout_item);
            linearLayout.measure(0, 0);
            // 其他方法获取的高度值会因View尚未被绘制而获取到0
            simpleItemHeight = linearLayout.getMeasuredHeight();
        }
    
        public int getSimpleItemHeight() {
            return simpleItemHeight;                // 5 * 2 + 28(dp) => 103(px)
        }
        
        public void setSupportPreview(boolean isSupportPreview){
            this.isSupportPreview = isSupportPreview;
        }
    
        public void setSupportPreview(boolean isSupportPreview, char previewChar){
            this.isSupportPreview = isSupportPreview;
            this.previewChar = previewChar;
        }
    
        @Override
        public int getCount() {
            return mObjects.size();
        }
    
        @Override
        public Object getItem(int position) {
            return mObjects.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.simple_dropdown_item_1line, null);
                holder.tv = (TextView) convertView.findViewById(R.id.tv_simple_item);
                holder.iv = (ImageView) convertView.findViewById(R.id.iv_simple_item);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.tv.setText(mObjects.get(position));
            holder.iv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String value = mObjects.remove(position);
    
                    if (mDeleteListener != null) {
                        mDeleteListener.onSimpleItemDeletedListener(value);
                    }
    
                    if (mFilterListener != null) {
                        mFilterListener.onFilterResultsListener(mObjects.size());
                    }
    
                    mOriginalValues.remove(value);
                    notifyDataSetChanged();
                }
            });
    
            return convertView;
        }
    
        private static class ViewHolder {
            TextView tv;
            ImageView iv;
        }
    
        public void setDefaultMode(int defaultMode) {
            this.defaultMode = defaultMode;
        }
    
        public void add(String item) {
            mOriginalValues.add(item);
            notifyDataSetChanged();         //
        }
    
        public void clear() {
            if(mOriginalValues != null && !mOriginalValues.isEmpty()) {
                mOriginalValues.clear();
                notifyDataSetChanged();         //
            }
        }
    
        // Interface
        public interface OnSimpleItemDeletedListener {
            void onSimpleItemDeletedListener(String value);
        }
    
        private OnSimpleItemDeletedListener mDeleteListener;
    
        public void setOnSimpleItemDeletedListener(OnSimpleItemDeletedListener listener) {
            this.mDeleteListener = listener;
        }
    
        // Interface
        public interface OnFilterResultsListener {
            void onFilterResultsListener(int count);
        }
    
        private OnFilterResultsListener mFilterListener;
    
        public void setOnFilterResultsListener(OnFilterResultsListener listener) {
            this.mFilterListener = listener;
        }
    
        @Override
        public Filter getFilter() {
            if (mArrayFilter == null) {
                mArrayFilter = new ArrayFilter(mFilterListener);
            }
            return mArrayFilter;
        }
    
        private class ArrayFilter extends Filter {
    
            private OnFilterResultsListener listener;
    
            public ArrayFilter(OnFilterResultsListener listener) {
                this.listener = listener;
            }
    
            @Override
            protected FilterResults performFiltering(CharSequence prefix) {
                FilterResults results = new FilterResults();
    
                if (mOriginalValues == null) {
                    synchronized (mLock) {
                        mOriginalValues = new ArrayList<>(mObjects);
                    }
                }
    
                if (prefix == null || prefix.length() == 0) {
                    synchronized (mLock) {
                        ArrayList<String> list = new ArrayList<>(mOriginalValues);
                        results.values = list;
                        results.count = list.size();
                    }
                } else {
                    if (isSupportPreview) {
                        int index = prefix.toString().indexOf(String.valueOf(previewChar));
                        if (index != -1) {
                            prefix = prefix.toString().substring(index + 1);
                        }
                    }
                
                    String prefixString = prefix.toString().toLowerCase();      // prefixString
                    final int count = mOriginalValues.size();                   // count
                    final ArrayList<String> newValues = new ArrayList<>(count); // newValues
    
                    for (int i = 0; i < count; i++) {
                        final String value = mOriginalValues.get(i);            // value
                        final String valueText = value.toLowerCase();           // valueText
    
                        // 1. 匹配所有
                        if ((defaultMode & MODE_CONTAINS) != MODE_NONE) {
                            if (valueText.contains(prefixString)) {
                                newValues.add(value);
                            }
                        } else {    // support: defaultMode = MODE_STARTSWITH | MODE_SPLIT
                            // 2. 匹配开头
                            if ((defaultMode & MODE_STARTSWITH) != MODE_NONE) {
                                if (valueText.startsWith(prefixString)) {
                                    newValues.add(value);
                                    isFound = true;
                                }
                            }
                            // 3. 分隔符匹配,效率低
                            if (!isFound && (defaultMode & MODE_SPLIT) != MODE_NONE) {
                                final String[] words = valueText.split(SPLIT_SEPARATOR);
                                for (String word : words) {
                                    if (word.startsWith(prefixString)) {
                                        newValues.add(value);
                                        break;
                                    }
                                }
                            }
                            if(isFound) {   // 若在MODE_STARTSWITH模式中匹配,则再次复位进行下一次判断
                                isFound = false;
                            }
                        }
    
                        if (maxMatch > 0) {             // 限制显示item的数目
                            if (newValues.size() > maxMatch - 1) {
                                break;
                            }
                        }
                    } // for (int i = 0; i < count; i++)
                    results.values = newValues;
                    results.count = newValues.size();
                }
    
                return results;
            }
    
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                //noinspection unchecked
                mObjects = (List<String>) results.values;
    
                if (results.count > 0) {
                    // 由于当删除提示框中的记录行时,而AutoCompleteTextView此时内容又不改变,故不会触发FilterResults事件
                    // 导致删除记录行时,提示框的高度不会发生相应的改变
                    // 解决方法:需要在ImageView的点击监听器中也调用OnFilterResultsListener.onFilterResultsListener()
                    // 来共同完成
                    if (listener != null) {
                        listener.onFilterResultsListener(results.count);
                    }
                    notifyDataSetChanged();
                } else {
                    notifyDataSetInvalidated();
                }
            }
        }
    }
    
    • 下拉提示框的item布局simple_dropdown_item_1line.xml

    这里需要固定父类控件LinearLayout的高度,在AutoCompleteAdapter中会获取其高度用于设置AutoCompleteTextView的下拉菜单的高度

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout_item"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="28dp"
        android:padding="5dp"
        android:gravity="center_vertical">
    
        <TextView
            android:id="@+id/tv_simple_item"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:paddingStart="5dp"
            android:paddingEnd="0dp"
            android:text="@string/text_nothing"
            android:textAllCaps="false"
            android:textSize="18sp"
            android:textColor="#000"/>
    
        <ImageView
            android:id="@+id/iv_simple_item"
            android:layout_width="18dp"
            android:layout_height="18dp"
            android:layout_marginEnd="5dp"
            android:src="@drawable/ic_action_name"
            android:contentDescription="@null"
            android:scaleType="fitCenter" />
    </LinearLayout>
    
    • 效果演示
    • 支持使用@字符来预览所有提示内容


    展开全文
  • layout的妙用
    layout代表着某一个view在父view中的位置,比如
    ViewGroup parent = new ViewGroup();
    View child = new View();
    parent.addView(child)
    child.layout(l,t,r,b);
    ps:用new 来初始化对象只是为了方便说明情况
    此时child是parent的子View,child.layout(l,t,r,b)就说明了child在parent放置的坐标位置,坐标原点(0,0)就是parent的左上角。

    其中(l,t)代表着左上角的位置,(r,b)代表着右下角的位置。

    使用案例,如下这个页面:该页面有多个view可以获取焦点,并在获取到焦点的view上赋予一个焦点框。


    刚开始实现这个页面的时候使用切图的方法,也就是把每个view的焦点框切一个图,放在

    <selector xmlns:android="http://schemas.android.com/apk/res/android" >
        <!--focus_img:焦点框图片-->
        <item android:state_focused="true" android:drawable="@drawable/focused_img"/>
        <item android:state_selected="true" android:drawable="@drawable/focused_img"/>
        <item android:state_pressed="true" android:drawable="@drawable/focused_img"></item>
        <item android:drawable="@drawable/unfocused_img"/>
    </selector>

    这中配置文件来让一个设置一个view的background.但是这样做有一个问题:这个页面有几个不同大小的view需要焦点框效果。也就是说要让美工针对不同的view来切不同的焦点框。要知道这只是应用的一个界面,还有其他的页面同样需要获取焦点框,那么就还得让美工切图。这样的话就得为每个焦点框配置一个selector这种重复性的工作。
    下面就用另外一种方法来,该是layout出场的时候了:

    思路:
    1)提供一个.9图片的焦点框(当然焦点框也可以用shape来实现焦点框)


    2)提供一个ImageView,这个ImageView的src就是.9图片,假设该ImageView的变量名为focusImgView
    3)对页面focusable为true的view设置FoncusChangeListener,如果某个view获取焦点的话,获取该view的左上角的位置(x,y)和它的宽度(width,height).然后设置
    focusImgView.layout(x,y,x+width,y+height)(因为android中没有直接的方法来获取某个view右下角的位置,所以需要通过宽和高来计算之)

    基本的代码如下:

    /**焦点框View**/
    public class FocusView extends ViewGroup{
        /**焦点框**/
    	private ImageView focusImgView;
    	/**页面中获取焦点的view**/
    	private View focusView;	
    	/*焦点.9图片*/
    	private Drawable mViewFocusDrawable;
    	public FocusView(Context context,Drawable mViewFocusDrawable) {
    		super(context);
    		init(mViewFocusDrawable);
    	}
    	
    	
    	private void init(Drawable mViewFocusDrawable) {
    		focusImgView = new  ImageView(getContext());
    		ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    		addView(focusImgView, params);
    		focusImgView.setBackgroundDrawable(mViewFocusDrawable);
    	}
    
    	/**
    	 * 设置焦点的图片
    	 * @param d
    	 */
    	public void setFocusDrawable(Drawable mViewFocusDrawable) {
    		focusImgView.setBackgroundDrawable(mViewFocusDrawable);
    	}
    	
    	/*
    	*@focusView 获取焦点的view
    	*/
    	public void showFocus(View focusView) {
    		
    		int[] location = new int[2];
    		focusView.getLocationInWindow(location);
    		int x = location[0];
    		int y = location[1];
    		int width = focusView.getWidth();
    		int height = focusView.getHeight();
    	        //这是重点步骤
    		focusImgView.layout(x, y,x+ width,y + height);
    	}
    
    
    	@Override
    	protected void onLayout(boolean changed, int l, int t, int r, int b) {
    	}
    	
    }
    
    在onFoucusChange方法里面这么调用:
    	@Override
    	public void onFocusChange(View view, boolean hasfocus) {
    
    		int viewId = view.getId();
    		switch (viewId) {
    		case R.id.demo_btn:
    			if (hasfocus) {
    				mFocusView.showFocus(view);
    			}
    			break;
    		}
    	}

    这样一个简单的.9图片就能够满足页面的应用:其他页面使用的效果图:


    展开全文
  • Layout(布局)

    2018-10-12 22:44:38
    布局容器有5个区域:北、南、东、西和中间。中间区域面板是必须的,边缘的面板都是可选的。...布局可以进行嵌套,用户可以通过组合布局构建复杂的布局结构   &lt;%@ page language="...utf-...

                    布局容器有5个区域:北、南、东、西和中间。中间区域面板是必须的,边缘的面板都是可选的。每个边缘区域面板都可以通过拖拽其边框改变大小,也可以点击折叠按钮将面板折叠起来。布局可以进行嵌套,用户可以通过组合布局构建复杂的布局结构

     

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>Layout:通过标签创建布局</title>
        <!-- 引入easyUI:JQuery文件支持 -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.min.js"></script>
      	<!-- 引入easyUI -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.easyui.min.js"></script>
      	<!-- 引入中文支持 -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/locale/easyui-lang-zh_CN.js"></script>
      	<!-- 引入easyUI主题css文件 -->
      	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/default/easyui.css" type="text/css"></link>
      	<!-- 引入easyUI 图标导航文件 -->
      	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/icon.css" type="text/css"></link></head>
      
      <body>
      	<%
    		/*
    			为div标签增加名为'easyui-layout'的类ID
    			region:布局面板位置;  title:布局面板标题;  split:true时可以通过分割栏改变面板大小
    			iconCls:包含图标的CSS类ID(icon-**)
    			可以在标签中间层输入html或文本
    		*/  	
      	 %>
    	<div id="cc" class="easyui-layout" style="width:600px;height:400px;">   
    		<div data-options="region:'north',title:'上',split:false" style="height:100px;">Up</div>   
    	    <div data-options="region:'south',title:'下',split:true" style="height:100px;">Down</div>   
    	    <div data-options="region:'east',iconCls:'icon-no',title:'东',split:true" style="width:100px;"></div>   
    	    <div data-options="region:'west',title:'西',split:true" style="width:100px;"></div>   
    	    <div data-options="region:'center',title:'中'" style="padding:5px;background:#eee;"><h1>墨渐生微</h1></div>   
    	</div>
      </body>
    </html>
    

     

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>Layout:使用完整页面创建布局</title>
        <!-- 引入easyUI:JQuery文件支持 -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.min.js"></script>
      	<!-- 引入easyUI -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.easyui.min.js"></script>
      	<!-- 引入中文支持 -->
      	<script type="text/javascript" src="js/jquery-easyui-1.3.4/locale/easyui-lang-zh_CN.js"></script>
      	<!-- 引入easyUI主题css文件 -->
      	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/default/easyui.css" type="text/css"></link>
      	<!-- 引入easyUI 图标导航文件 -->
      	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/icon.css" type="text/css"></link></head>
      
    	<body class="easyui-layout">
    		 <%
    			/*
    				为div标签增加名为'easyui-layout'的类ID
    				region:布局面板位置;  title:布局面板标题;  split:true时可以通过分割栏改变面板大小
    				iconCls:包含图标的CSS类ID(icon-**)
    			*/  	
    	  	 %>	  
    	    <div data-options="region:'north',title:'North Title',split:true" style="height:100px;"></div>   
    	    <div data-options="region:'south',title:'South Title',split:true" style="height:100px;"></div>   
    	    <div data-options="region:'east',iconCls:'icon-reload',title:'East',split:true" style="width:100px;"></div>   
    	    <div data-options="region:'west',title:'West',split:true" style="width:100px;"></div>   
    	    <div data-options="region:'center',title:'center title'" style="padding:5px;background:#eee;"></div>   
    	</body> 
    </html>
    

     

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    	<head>
    	    <title>Layout:嵌套布局</title>
    	    <!-- 引入easyUI:JQuery文件支持 -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.min.js"></script>
    	  	<!-- 引入easyUI -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.easyui.min.js"></script>
    	  	<!-- 引入中文支持 -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/locale/easyui-lang-zh_CN.js"></script>
    	  	<!-- 引入easyUI主题css文件 -->
    	  	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/default/easyui.css" type="text/css"></link>
    	  	<!-- 引入easyUI 图标导航文件 -->
    	  	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/icon.css" type="text/css"></link>
    	</head>
      
    	<body class="easyui-layout">
    		<%
    			/*
    				fit:布局组件将自适应父容器
    				collapsed:是否显示折叠按钮
    			*/  	
    	  	 %>   
    	    <div data-options="region:'north'" style="height:100px"></div>   
    	    <div data-options="region:'center'">   
    	        <div class="easyui-layout" data-options="fit:true">   
    	            <div data-options="region:'west',collapsed:true" style="width:180px"></div>   
    	            <div data-options="region:'center'"></div>   
    	        </div>   
    	    </div>   
    	</body> 
    </html>
    

     

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    	<head>
    	    <title>JS代码创建布局</title>
    	    <!-- 引入easyUI:JQuery文件支持 -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.min.js"></script>
    	  	<!-- 引入easyUI -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/jquery.easyui.min.js"></script>
    	  	<!-- 引入中文支持 -->
    	  	<script type="text/javascript" src="js/jquery-easyui-1.3.4/locale/easyui-lang-zh_CN.js"></script>
    	  	<!-- 引入easyUI主题css文件 -->
    	  	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/default/easyui.css" type="text/css"></link>
    	  	<!-- 引入easyUI 图标导航文件 -->
    	  	<link rel="stylesheet" href="js/jquery-easyui-1.3.4/themes/icon.css" type="text/css"></link>
    	  	
    	  	<script type="text/javascript">
    	  		$(document).ready(function(){
    		  		$('#cc').layout('add',{    
    				    region: 'west',    
    				    width: 180,    
    				    title: '西',    
    				    split: true,    
    				    tools: [{    
    					        iconCls:'icon-add',    
    					        handler:function(){alert('add');}    
    					    },{    
    					        iconCls:'icon-remove',    
    					        handler:function(){alert('remove');}    
    					    }]
    				});
    	  		});  		
    	  	</script>
    	</head>
      
    	<body>
    		<div id="cc" class="easyui-layout" style="width:600px;height:400px;"> 
    			<div data-options="region:'center',title:'center title'" style="padding:5px;background:#eee;"></div> 
    		</div>
    	</body> 
    </html>
    

     

    展开全文
  • vue、Layout 布局、Layout 属性、vue Layout 全部布局、vue Layout 全部属性

    设计规则

    协助进行页面级整体布局。

    尺寸

    一级导航项偏左靠近 logo 放置,辅助菜单偏右放置。

    • 顶部导航(大部分系统):一级导航高度 64px,二级导航 48px
    • 顶部导航(展示类页面):一级导航高度 80px,二级导航 56px
    • 顶部导航高度的范围计算公式为:48+8n
    • 侧边导航宽度的范围计算公式:200+8n

    交互

    • 一级导航和末级的导航需要在可视化的层面被强调出来;
    • 当前项应该在呈现上优先级最高;
    • 当导航收起的时候,当前项的样式自动赋予给它的上一个层级;
    • 左侧导航栏的收放交互同时支持手风琴和全展开的样式,根据业务的要求进行适当的选择。

    视觉

    导航样式上需要根据信息层级合理的选择样式:

    • 大色块强调

    建议用于底色为深色系时,当前页面父级的导航项。

    • 高亮火柴棍

    当导航栏底色为浅色系时使用,可用于当前页面对应导航项,建议尽量在导航路径的最终项使用。

    • 字体高亮变色

    从可视化层面,字体高亮的视觉强化力度低于大色块,通常在当前项的上一级使用。

    • 字体放大

    12px14px 是导航的标准字号,14 号字体用在一、二级导航中。字号可以考虑导航项的等级做相应选择。

    组件概述

    Layout:布局容器,其下可嵌套 Header Sider Content FooterLayout 本身,可以放在任何父容器中。
    Header:顶部布局,自带默认样式,其下可嵌套任何元素,只能放在 Layout 中。
    Sider:侧边栏,自带默认样式及基本功能,其下可嵌套任何元素,只能放在 Layout 中。
    Content:内容部分,自带默认样式,其下可嵌套任何元素,只能放在 Layout中。
    Footer:底部布局,自带默认样式,其下可嵌套任何元素,只能放在 Layout中。

    代码演示

    1.基本结构

    在这里插入图片描述
    典型的页面布局。

    <template>
      <div id="components-layout-demo-basic">
        <a-layout>
          <a-layout-header>Header</a-layout-header>
          <a-layout-content>Content</a-layout-content>
          <a-layout-footer>Footer</a-layout-footer>
        </a-layout>
    
        <a-layout>
          <a-layout-header>Header</a-layout-header>
          <a-layout>
            <a-layout-sider>Sider</a-layout-sider>
            <a-layout-content>Content</a-layout-content>
          </a-layout>
          <a-layout-footer>Footer</a-layout-footer>
        </a-layout>
    
        <a-layout>
          <a-layout-header>Header</a-layout-header>
          <a-layout>
            <a-layout-content>Content</a-layout-content>
            <a-layout-sider>Sider</a-layout-sider>
          </a-layout>
          <a-layout-footer>Footer</a-layout-footer>
        </a-layout>
    
        <a-layout>
          <a-layout-sider>Sider</a-layout-sider>
          <a-layout>
            <a-layout-header>Header</a-layout-header>
            <a-layout-content>Content</a-layout-content>
            <a-layout-footer>Footer</a-layout-footer>
          </a-layout>
        </a-layout>
      </div>
    </template>
    <style>
    #components-layout-demo-basic {
      text-align: center;
    }
    #components-layout-demo-basic .ant-layout-header,
    #components-layout-demo-basic .ant-layout-footer {
      background: #7dbcea;
      color: #fff;
    }
    #components-layout-demo-basic .ant-layout-footer {
      line-height: 1.5;
    }
    #components-layout-demo-basic .ant-layout-sider {
      background: #3ba0e9;
      color: #fff;
      line-height: 120px;
    }
    #components-layout-demo-basic .ant-layout-content {
      background: rgba(16, 142, 233, 1);
      color: #fff;
      min-height: 120px;
      line-height: 120px;
    }
    #components-layout-demo-basic > .ant-layout {
      margin-bottom: 48px;
    }
    #components-layout-demo-basic > .ant-layout:last-child {
      margin: 0;
    }
    </style>
    

    2.自定义触发器

    在这里插入图片描述
    要使用自定义触发器,可以设置 :trigger="null" 来隐藏默认设定。

    <template>
      <a-layout id="components-layout-demo-custom-trigger">
        <a-layout-sider
          :trigger="null"
          collapsible
          v-model="collapsed"
        >
          <div class="logo" />
          <a-menu theme="dark" mode="inline" :defaultSelectedKeys="['1']">
            <a-menu-item key="1">
              <a-icon type="user" />
              <span>nav 1</span>
            </a-menu-item>
            <a-menu-item key="2">
              <a-icon type="video-camera" />
              <span>nav 2</span>
            </a-menu-item>
            <a-menu-item key="3">
              <a-icon type="upload" />
              <span>nav 3</span>
            </a-menu-item>
          </a-menu>
        </a-layout-sider>
        <a-layout>
          <a-layout-header style="background: #fff; padding: 0">
            <a-icon
              class="trigger"
              :type="collapsed ? 'menu-unfold' : 'menu-fold'"
              @click="()=> collapsed = !collapsed"
            />
          </a-layout-header>
          <a-layout-content :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }">
            Content
          </a-layout-content>
        </a-layout>
      </a-layout>
    </template>
    <script>
    export default {
      data(){
        return {
          collapsed: false,
        }
      },
    }
    </script>
    <style>
    #components-layout-demo-custom-trigger .trigger {
      font-size: 18px;
      line-height: 64px;
      padding: 0 24px;
      cursor: pointer;
      transition: color .3s;
    }
    
    #components-layout-demo-custom-trigger .trigger:hover {
      color: #1890ff;
    }
    
    #components-layout-demo-custom-trigger .logo {
      height: 32px;
      background: rgba(255,255,255,.2);
      margin: 16px;
    }
    </style>
    

    3.顶部-侧边布局-通栏

    在这里插入图片描述
    同样拥有顶部导航及侧边栏,区别是两边未留边距,多用于应用型的网站。

    <template>
      <a-layout id="components-layout-demo-top-side-2">
        <a-layout-header class="header">
          <div class="logo" />
          <a-menu
            theme="dark"
            mode="horizontal"
            :defaultSelectedKeys="['2']"
            :style="{ lineHeight: '64px' }"
          >
            <a-menu-item key="1">nav 1</a-menu-item>
            <a-menu-item key="2">nav 2</a-menu-item>
            <a-menu-item key="3">nav 3</a-menu-item>
          </a-menu>
        </a-layout-header>
        <a-layout>
          <a-layout-sider width="200" style="background: #fff">
            <a-menu
              mode="inline"
              :defaultSelectedKeys="['1']"
              :defaultOpenKeys="['sub1']"
              :style="{ height: '100%', borderRight: 0 }"
            >
              <a-sub-menu key="sub1">
                <span slot="title"><a-icon type="user" />subnav 1</span>
                <a-menu-item key="1">option1</a-menu-item>
                <a-menu-item key="2">option2</a-menu-item>
                <a-menu-item key="3">option3</a-menu-item>
                <a-menu-item key="4">option4</a-menu-item>
              </a-sub-menu>
              <a-sub-menu key="sub2">
                <span slot="title"><a-icon type="laptop" />subnav 2</span>
                <a-menu-item key="5">option5</a-menu-item>
                <a-menu-item key="6">option6</a-menu-item>
                <a-menu-item key="7">option7</a-menu-item>
                <a-menu-item key="8">option8</a-menu-item>
              </a-sub-menu>
              <a-sub-menu key="sub3">
                <span slot="title"><a-icon type="notification" />subnav 3</span>
                <a-menu-item key="9">option9</a-menu-item>
                <a-menu-item key="10">option10</a-menu-item>
                <a-menu-item key="11">option11</a-menu-item>
                <a-menu-item key="12">option12</a-menu-item>
              </a-sub-menu>
            </a-menu>
          </a-layout-sider>
          <a-layout style="padding: 0 24px 24px">
            <a-breadcrumb style="margin: 16px 0">
              <a-breadcrumb-item>Home</a-breadcrumb-item>
              <a-breadcrumb-item>List</a-breadcrumb-item>
              <a-breadcrumb-item>App</a-breadcrumb-item>
            </a-breadcrumb>
            <a-layout-content :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }">
              Content
            </a-layout-content>
          </a-layout>
        </a-layout>
      </a-layout>
    </template>
    <script>
    export default {
      data () {
        return {
          collapsed: false,
        }
      },
    }
    </script>
    
    <style>
    #components-layout-demo-top-side-2 .logo {
      width: 120px;
      height: 31px;
      background: rgba(255,255,255,.2);
      margin: 16px 28px 16px 0;
      float: left;
    }
    </style>
    

    4.顶部-侧边布局

    在这里插入图片描述
    拥有顶部导航及侧边栏的页面,多用于展示类网站。

    <template>
      <a-layout id="components-layout-demo-top-side">
        <a-layout-header class="header">
          <div class="logo" />
          <a-menu
            theme="dark"
            mode="horizontal"
            :defaultSelectedKeys="['2']"
            :style="{ lineHeight: '64px' }"
          >
            <a-menu-item key="1">nav 1</a-menu-item>
            <a-menu-item key="2">nav 2</a-menu-item>
            <a-menu-item key="3">nav 3</a-menu-item>
          </a-menu>
        </a-layout-header>
        <a-layout-content style="padding: 0 50px">
          <a-breadcrumb style="margin: 16px 0">
            <a-breadcrumb-item>Home</a-breadcrumb-item>
            <a-breadcrumb-item>List</a-breadcrumb-item>
            <a-breadcrumb-item>App</a-breadcrumb-item>
          </a-breadcrumb>
          <a-layout style="padding: 24px 0; background: #fff">
            <a-layout-sider width="200" style="background: #fff">
              <a-menu
                mode="inline"
                :defaultSelectedKeys="['1']"
                :defaultOpenKeys="['sub1']"
                style="height: 100%"
              >
                <a-sub-menu key="sub1">
                  <span slot="title"><a-icon type="user" />subnav 1</span>
                  <a-menu-item key="1">option1</a-menu-item>
                  <a-menu-item key="2">option2</a-menu-item>
                  <a-menu-item key="3">option3</a-menu-item>
                  <a-menu-item key="4">option4</a-menu-item>
                </a-sub-menu>
                <a-sub-menu key="sub2">
                  <span slot="title"><a-icon type="laptop" />subnav 2</span>
                  <a-menu-item key="5">option5</a-menu-item>
                  <a-menu-item key="6">option6</a-menu-item>
                  <a-menu-item key="7">option7</a-menu-item>
                  <a-menu-item key="8">option8</a-menu-item>
                </a-sub-menu>
                <a-sub-menu key="sub3">
                  <span slot="title"><a-icon type="notification" />subnav 3</span>
                  <a-menu-item key="9">option9</a-menu-item>
                  <a-menu-item key="10">option10</a-menu-item>
                  <a-menu-item key="11">option11</a-menu-item>
                  <a-menu-item key="12">option12</a-menu-item>
                </a-sub-menu>
              </a-menu>
            </a-layout-sider>
            <a-layout-content :style="{ padding: '0 24px', minHeight: '280px' }">
              Content
            </a-layout-content>
          </a-layout>
        </a-layout-content>
        <a-layout-footer style="text-align: center">
          Ant Design ©2018 Created by Ant UED
        </a-layout-footer>
      </a-layout>
    </template>
    
    <style>
    #components-layout-demo-top-side .logo {
      width: 120px;
      height: 31px;
      background: rgba(255,255,255,.2);
      margin: 16px 28px 16px 0;
      float: left;
    }
    </style>
    

    5.上中下布局

    在这里插入图片描述
    最基本的『上-中-下』布局。
    一般主导航放置于页面的顶端,从左自右依次为:logo、一级导航项、辅助菜单(用户、设置、通知等)。通常将内容放在固定尺寸(例如:1200px)内,整个页面排版稳定,不受用户终端显示器影响;上下级的结构符合用户上下浏览的习惯,也是较为经典的网站导航模式。页面上下切分的方式提高了主工作区域的信息展示效率,但在纵向空间上会有一些牺牲。此外,由于导航栏水平空间的限制,不适合那些一级导航项很多的信息结构。

    <template>
      <a-layout id="components-layout-demo-top" class="layout">
        <a-layout-header>
          <div class="logo" />
          <a-menu
            theme="dark"
            mode="horizontal"
            :defaultSelectedKeys="['2']"
            :style="{ lineHeight: '64px' }"
          >
            <a-menu-item key="1">nav 1</a-menu-item>
            <a-menu-item key="2">nav 2</a-menu-item>
            <a-menu-item key="3">nav 3</a-menu-item>
          </a-menu>
        </a-layout-header>
        <a-layout-content style="padding: 0 50px">
          <a-breadcrumb style="margin: 16px 0">
            <a-breadcrumb-item>Home</a-breadcrumb-item>
            <a-breadcrumb-item>List</a-breadcrumb-item>
            <a-breadcrumb-item>App</a-breadcrumb-item>
          </a-breadcrumb>
          <div :style="{ background: '#fff', padding: '24px', minHeight: '280px' }">Content</div>
        </a-layout-content>
        <a-layout-footer style="text-align: center">
          Ant Design ©2018 Created by Ant UED
        </a-layout-footer>
      </a-layout>
    </template>
    <style>
    #components-layout-demo-top .logo {
      width: 120px;
      height: 31px;
      background: rgba(255,255,255,.2);
      margin: 16px 24px 16px 0;
      float: left;
    }
    </style>
    

    6.响应式布局

    在这里插入图片描述
    Layout.Sider 支持响应式布局。

    说明:配置 breakpoint 属性即生效,视窗宽度小于 breakpoint 时 Sider 缩小为 collapsedWidth 宽度,若将 collapsedWidth 设置为零,会出现特殊 trigger。

    <template>
      <a-layout id="components-layout-demo-responsive">
        <a-layout-sider
          breakpoint="lg"
          collapsedWidth="0"
          @collapse="onCollapse"
          @breakpoint="onBreakpoint"
        >
          <div class="logo" />
          <a-menu theme="dark" mode="inline" :defaultSelectedKeys="['4']">
            <a-menu-item key="1">
              <a-icon type="user" />
              <span class="nav-text">nav 1</span>
            </a-menu-item>
            <a-menu-item key="2">
              <a-icon type="video-camera" />
              <span class="nav-text">nav 2</span>
            </a-menu-item>
            <a-menu-item key="3">
              <a-icon type="upload" />
              <span class="nav-text">nav 3</span>
            </a-menu-item>
            <a-menu-item key="4">
              <a-icon type="user" />
              <span class="nav-text">nav 4</span>
            </a-menu-item>
          </a-menu>
        </a-layout-sider>
        <a-layout>
          <a-layout-header :style="{ background: '#fff', padding: 0 }" />
          <a-layout-content :style="{ margin: '24px 16px 0' }">
            <div :style="{ padding: '24px', background: '#fff', minHeight: '360px' }">
              content
            </div>
          </a-layout-content>
          <a-layout-footer style="textAlign: center">
            Ant Design ©2018 Created by Ant UED
          </a-layout-footer>
        </a-layout>
      </a-layout>
    </template>
    <script>
    export default {
      methods: {
        onCollapse(collapsed, type) {
          console.log(collapsed, type);
        },
        onBreakpoint(broken) {
          console.log(broken);
        }
      }
    }
    </script>
    
    <style>
    #components-layout-demo-responsive .logo {
      height: 32px;
      background: rgba(255,255,255,.2);
      margin: 16px;
    }
    </style>
    

    7.固定侧边栏

    在这里插入图片描述
    当内容较长时,使用固定侧边栏可以提供更好的体验。

    <template>
      <a-layout id="components-layout-demo-fixed-sider">
        <a-layout-sider :style="{ overflow: 'auto', height: '100vh', position: 'fixed', left: 0 }">
          <div class="logo"></div>
          <a-menu theme="dark" mode="inline" :defaultSelectedKeys="['4']">
            <a-menu-item key="1">
              <a-icon type="user" />
              <span class="nav-text">nav 1</span>
            </a-menu-item>
            <a-menu-item key="2">
              <a-icon type="video-camera" />
              <span class="nav-text">nav 2</span>
            </a-menu-item>
            <a-menu-item key="3">
              <a-icon type="upload" />
              <span class="nav-text">nav 3</span>
            </a-menu-item>
            <a-menu-item key="4">
              <a-icon type="bar-chart" />
              <span class="nav-text">nav 4</span>
            </a-menu-item>
            <a-menu-item key="5">
              <a-icon type="cloud-o" />
              <span class="nav-text">nav 5</span>
            </a-menu-item>
            <a-menu-item key="6">
              <a-icon type="appstore-o" />
              <span class="nav-text">nav 6</span>
            </a-menu-item>
            <a-menu-item key="7">
              <a-icon type="team" />
              <span class="nav-text">nav 7</span>
            </a-menu-item>
            <a-menu-item key="8">
              <a-icon type="shop" />
              <span class="nav-text">nav 8</span>
            </a-menu-item>
          </a-menu>
        </a-layout-sider>
        <a-layout :style="{ marginLeft: '200px' }">
          <a-layout-header :style="{ background: '#fff', padding: 0 }" />
          <a-layout-content :style="{ margin: '24px 16px 0', overflow: 'initial' }">
            <div :style="{ padding: '24px', background: '#fff', textAlign: 'center' }">
              ...
              <br />
              Really
              <br />...<br />...<br />...<br />
              long
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />...
              <br />...<br />...<br />...<br />...<br />...<br />
              content
            </div>
          </a-layout-content>
          <a-layout-footer :style="{ textAlign: 'center' }">
            Ant Design ©2018 Created by Ant UED
          </a-layout-footer>
        </a-layout>
      </a-layout>
    </template>
    <style>
    #components-layout-demo-fixed-sider .logo {
      height: 32px;
      background: rgba(255,255,255,.2);
      margin: 16px;
    }
    </style>
    

    8.固定头部

    在这里插入图片描述
    一般用于固定顶部导航,方便页面切换。

    <template>
      <a-layout id="components-layout-demo-fixed">
        <a-layout-header :style="{ position: 'fixed', zIndex: 1, width: '100%' }">
          <div class="logo" />
          <a-menu
            theme="dark"
            mode="horizontal"
            :defaultSelectedKeys="['2']"
            :style="{ lineHeight: '64px' }"
          >
            <a-menu-item key="1">nav 1</a-menu-item>
            <a-menu-item key="2">nav 2</a-menu-item>
            <a-menu-item key="3">nav 3</a-menu-item>
          </a-menu>
        </a-layout-header>
        <a-layout-content :style="{ padding: '0 50px', marginTop: '64px' }">
          <a-breadcrumb :style="{ margin: '16px 0' }">
            <a-breadcrumb-item>Home</a-breadcrumb-item>
            <a-breadcrumb-item>List</a-breadcrumb-item>
            <a-breadcrumb-item>App</a-breadcrumb-item>
          </a-breadcrumb>
          <div :style="{ background: '#fff', padding: '24px', minHeight: '380px' }">Content</div>
        </a-layout-content>
        <a-layout-footer :style="{ textAlign: 'center' }">
          Ant Design ©2018 Created by Ant UED
        </a-layout-footer>
      </a-layout>
    </template>
    <style>
    #components-layout-demo-fixed .logo {
      width: 120px;
      height: 31px;
      background: rgba(255,255,255,.2);
      margin: 16px 24px 16px 0;
      float: left;
    }
    </style>
    

    9.侧边布局

    在这里插入图片描述
    侧边两列式布局。页面横向空间有限时,侧边导航可收起。
    侧边导航在页面布局上采用的是左右的结构,一般主导航放置于页面的左侧固定位置,辅助菜单放置于工作区顶部。内容根据浏览器终端进行自适应,能提高横向空间的使用率,但是整个页面排版不稳定。侧边导航的模式层级扩展性强,一、二、三级导航项目可以更为顺畅且具关联性的被展示,同时侧边导航可以固定,使得用户在操作和浏览中可以快速的定位和切换当前位置,有很高的操作效率。但这类导航横向页面内容的空间会被牺牲一部份。

    API

    <Layout>
      <Header>header</Header>
      <Layout>
        <Sider>left sidebar</Sider>
        <Content>main content</Content>
        <Sider>right sidebar</Sider>
      </Layout>
      <Footer>footer</Footer>
    </Layout>
    

    Layout 布局容器

    参数 说明 类型 默认值
    class 容器 class string -
    style 指定样式 object -
    hasSider 表示子元素里有 Sider,一般不用指定。可用于服务端渲染时避免样式闪动 boolean -

    Layout.Header Layout.Footer Layout.Content API 与 Layout 相同

    Layout.Sider 侧边栏

    参数 说明 类型 默认值
    breakpoint 触发响应式布局的断点 Enum { 'xs', 'sm', 'md', 'lg', 'xl', 'xxl' } -
    class 容器 class string -
    collapsed(v-model) 当前收起状态 boolean -
    collapsedWidth 收缩宽度,设置为 0 会出现特殊 trigger number 80
    collapsible 是否可收起 boolean false
    defaultCollapsed 是否默认收起 boolean false
    reverseArrow 翻转折叠提示箭头的方向,当 Sider 在右边时可以使用 boolean false
    style 指定样式 object|string -
    theme 主题颜色 string: light dark dark
    trigger 自定义 trigger,设置为 null 时隐藏 trigger string|slot -
    width 宽度 number|string 200

    事件

    事件名称 说明 回调参数
    collapse 展开-收起时的回调函数,有点击 trigger 以及响应式反馈两种方式可以触发 (collapsed, type) => {}
    breakpoint 触发响应式布局断点时的回调 (broken) => {}

    breakpoint width

    {
    xs: ‘480px’,
    sm: ‘576px’,
    md: ‘768px’,
    lg: ‘992px’,
    xl: ‘1200px’,
    xxl: ‘1600px’,
    }

    展开全文
  • Layout

    2019-07-15 16:11:34
    触摸按键设计Layout IC要放在PAD的中央,保证左右PAD走线最短和对称 PAD到IC的连线越短越好、线径使用最小线宽、走线不要和PAD同一层 触摸PAD的背面PCB不能走线(时钟) PAD旁边和背面不要不要铺地,如果需要...

    触摸按键设计Layout

    • IC要放在PAD的中央,保证左右PAD走线最短和对称
      在这里插入图片描述
    • PAD到IC的连线越短越好、线径使用最小线宽、走线不要和PAD同一层
    • 触摸PAD的背面PCB不能走线(时钟)
    • PAD旁边和背面不要不要铺地,如果需要铺地,距离PAD边缘2mm
    • PAD & PAD之间的走线,线与线的距离线宽

      并行3Cm,线间距 1mm
      并行5Cm,线间距 1.5mm
      并行7Cm,线间距 2mm
      大于7cm线与线之间需要底线隔离

    • 如果成本允许,使用独立的LDO给触摸IC供电,不要和其他电路共用电源回路(如图1)。
      在这里插入图片描述在这里插入图片描述
      如果做不到完全独立,也应该保证供电的电源先进入触摸IC的电源,然后再供给其他电源,减小其他电路电源上产生的噪声对触摸IC的影响
      在这里插入图片描述
    • 两个焊盘之间至少保持0.5mm以上,以避免相邻按键在侦测KEY时发生相互干扰
      在这里插入图片描述
    • PAD 之间的距离过小时,需要加地线隔离
    • PAD 不用大面积GND包围,最少预留0.4mm以上的安全间距,采用网格地网格大小为1mm*1mm
      在这里插入图片描述

    充电ICLayout

    在这里插入图片描述

    • ISET引脚的RISET应尽可能接近CN3065,ISET引脚的寄生电容应尽可能小。

    • VIN引脚和BAT引脚的电容应尽可能接近CN3065。

    • 在充电期间,CN3065的温度可能很高,NTC热敏电阻应放置在足够远的CN3065,以便热敏电阻可以正确反映电池的温度。

    • 使用良好的热PC板布局来最大化充电电流非常重要。 IC产生的热量的热路径是从芯片到铜引线框架,通过封装引线(特别是接地引线)到PC板铜,PC板铜是散热器。 足迹铜焊盘应尽可能宽,并扩展到较大的铜区域以扩散并将热量散发到周围环境。 内部或背面铜层的馈通通孔也可用于改善充电器的整体热性能。
      在设计PC板布局时,还必须考虑电路板上与充电器无关的其他热源,因为它们会影响整体温升和最大充电电流。

    • 在所有条件下提供最大充电电流的能力要求将CN3065封装背面的裸露金属焊盘焊接到PC板地。 未能在封装背面的裸露焊盘和铜板之间进行热接触将导致更大的热阻。

      SIM 卡Layout

      在这里插入图片描述
      SIM卡电路比较容易受到干扰,引起不识卡或掉卡等情况,所以在设计时请遵循以下原则: 

    • 在 PCB 布局阶段一定要将 SIM 卡座远离 GSM 天线; 

    • SIM 卡走线要尽量远离 RF 线、VBAT 和高速信号线,同时 SIM 卡走线不要太长; 

    • SIM 卡座的 GND 要和模块的 GND 保持良好的联通性,使二者 GND 等电位;

    • 为防止 SIM_CLK 对其他信号干扰,建议将 SIM_CLK 做保护处理; 

    • 建议在 SIM_VDD 信号线上靠近 SIM 卡座放置一个 100nF 电容; 

    • 在靠近 SIM 卡座的地方放置 TVS,该 TVS 的寄生电容不应大于 50pF 的,和模块之间串联 51Ω电 阻可以增强 ESD 防护; 

    • SIM 卡信号线增加 22pf 对地电容,防止射频干扰。

    展开全文
  • 今天给大家带来2017年的第一篇文章,这里先祝大家新年好。 本篇文章的主题是ConstraintLayout。其实ConstraintLayout是Android Studio 2.2中主要的新增功能之一,也是Google在去年的I/O大会上重点宣传的一个功能。...
  • Vlayout使用详细介绍

    2018-10-17 18:38:20
    Vlayout使用详细介绍 目录介绍 1.Vlayout简单介绍 2.主要功能介绍 2.1 主要功能的思维导图 2.2 主要功能说明 .使用方法与案例 3.1 初始化 3.2 设置回收复用池 ...4.1 VirtualLayoutAdapte
  • gdb调试的layout使用

    2013-08-21 16:41:24
    layout:用于分割窗口,可以一边查看代码,一边测试。主要有以下几种用法: layout src:显示源代码窗口 layout asm:显示汇编窗口 layout regs:显示源代码/汇编和寄存器窗口 layout split:显示源代码和汇编窗口 ...
  • R语言中layout()函数的用法
  • android VLayout 全面解析

    2017-11-15 21:01:56
    概述前不久,阿里新开源了2个东西,Atlas和vlayout。今天我来介绍下vlayout的使用。在介绍前,先抱怨两句,阿里放开源出来,感觉就是让我们这群人给他们找bug~~我曾遇到一个奇怪的问题,然后一直以为自己写的有问题...
  • 在进行UI布局的时候,可能经常会用到 android:gravity 和 android:layout_Gravity 这两个属性。 关于这两个属性的区别,网上已经有很多人进行了说明,这边再简单说一下。 (资料来自网络) LinearLayout有两个非常...
  • 之所以android:layout_weight会引起争议,是因为在设置该属性的同时,设置android:layout_width为wrap_content和match_parent会造成两种截然相反的效果。如下所示: android:layout_width="match_parent
  • 新建MVC的项目时会自动创建_ViewStart.cshtml、_Layout.cshtml页面,这样我们就把公共的部分放到_Layout页面中,每次新建页面时都会自动加载_ViewStart。 _ViewStart.cshtml页面代码: @{ Layout = "~/Views/...
  • Layout,翻译为中文的意思是 布局,安排,版面设计。对于许多的组件的命令,都有Layout_x和x 的区别,而许多的区别很明显,直接是Layout是相对于父容器(一般就是整个xml的布局)的改变,一个是相对于组件本身的...
  • ASPMVC- Layout 使用

    2018-07-03 09:41:31
    在ASP MVC模式中,采用Layout策略实现了网站主体布局的搭建,采用Layout后,应用系统只需要专心于各种业务页面的开发,通过Layout实现系统布局,完成各种页面的切换。在aspmvc框架下,默认模板中,采用Layout策略时...
  • 1.首先来看看android:layout_gravity和android:gravity的使用区别。 android:gravity: 这个是针对控件里的元素来说的,用来控制元素在该控件里的显示位置。例如,在一个Button按钮控件中设置如下两个属性, ...
  • 8.4.6 从右到左布局(RTL Layout) 从Android 4.2开始,Android SDK支持一种从右到左(RTL,Right-to-Left)UI布局的方式,尽管这种布局方式经常被使用在诸如阿拉伯语、希伯来语等环境中,中国用户很少使用。...
  • 1.在 src/components目录下新建Layout.vue文件: &lt;template&gt; &lt;div&gt; &lt;h2&gt;header&lt;/h2&gt; &lt;h2&gt;content&lt;/h2&gt; &lt;h2&...
  • 布局文件,作为android中必...系统布局文件:android.R.layout.xxx; 用户自定义布局文件:R.layout.xxx; 那系统布局文件究竟有哪一些,大家在用的时候如果不了解,心里估计有点惴惴。现在下方图中列出所有系统布局,
  • 该框架的参考原型是ExtJS的border-layout,因此十分适用于将原有使用ExtJS的项目改造成jQuery项目。其核心是一个大小自适应的中心面板(必选),面板的上下左右四个方向可以放置可折叠、可缩放的面板(可选),各个...
1 2 3 4 5 ... 20
收藏数 866,951
精华内容 346,780
关键字:

layout