• 可伸缩悬浮搜索框


    需求:

    1.页面上悬浮一个搜索框,点击可伸缩

    2.可以搜索上一个下一个

    3.搜索标题内容

    效果图:

    注意点:

    1.起始一个搜索小图片,终止一长条搜索框,中间用View做一个动画,这三个都是CardView

    2.为了处处使用,封装了起来

    3.搜索到的内容放进一个list,保存位置,点击上一个下一个滑动

    4.输入框输入后自动搜索第一个

    5.在特定情况下提示“没有搜索结果”,“已经是第一个了”,“已经是最后一个了”

    6.分页后刷新list内容

    7.搜索到的内容滑动搜索框正下方,由于recyclerView的原因,需要重写LinearLayoutManager

    public class FloatSearchView {
        private Context context;
        private CardView largeLayout;
        private CardView smallLayout;
        private CardView animView;
        private RecyclerView recyclerView;
        private List<Object> list;
        private String className;
        private String attrName;
    
        public FloatSearchView(Context context, RecyclerView recyclerView, CardView largeLayout,
                               CardView smallLayout, CardView animView, String className, String attrName) {
            this.context = context;
            this.recyclerView = recyclerView;
            this.largeLayout = largeLayout;
            this.smallLayout = smallLayout;
            this.animView = animView;
            this.className = className;
            this.attrName = attrName;
        }
    
        private List<Integer> searchList;
        private int searchCursor;
        private EditText editText;
        private Toast toast = null;
    
        public void init() {
            list = new ArrayList<>();
            searchList = new ArrayList<>();
            editText = (EditText) largeLayout.findViewById(R.id.editText);
            ImageView close = (ImageView) largeLayout.findViewById(R.id.close);
            ImageView previous = (ImageView) largeLayout.findViewById(R.id.previous);
            ImageView next = (ImageView) largeLayout.findViewById(R.id.next);
            editText.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
                }
    
                @Override
                public void afterTextChanged(Editable editable) {
                    if (editText.getText().toString().length() > 0) {
                        firstSearch();
                    } else {
                        searchCursor = 0;
                        searchList.clear();
                    }
                }
            });
            smallLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    searchViewLarger();
                }
            });
            close.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    searchViewSmaller();
                    editText.setText("");
                    searchCursor = 0;
                    searchList.clear();
                    hideInput();
                }
            });
            previous.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (searchList.size() == 0) {
                        checkToastResult();
                        return;
                    }
                    if (searchCursor - 1 >= 0) {
                        searchCursor--;
                        recyclerView.smoothScrollToPosition(searchList.get(searchCursor));
                    } else {
                        if (toast != null) {
                            toast.cancel();
                        }
                        toast = Toast.makeText(context, "已经是第一个了", Toast.LENGTH_SHORT);
                        toast.show();
                    }
                }
            });
            next.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (searchList.size() == 0) {
                        checkToastResult();
                        return;
                    }
                    if (searchCursor + 1 <= searchList.size() - 1) {
                        searchCursor++;
                        recyclerView.smoothScrollToPosition(searchList.get(searchCursor));
                    } else {
                        if (toast != null) {
                            toast.cancel();
                        }
                        toast = Toast.makeText(context, "已经是最后一个了", Toast.LENGTH_SHORT);
                        toast.show();
                    }
                }
            });
        }
    
        private void hideInput() {
            InputMethodManager manager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (((Activity) context).getWindow().getAttributes().softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN) {
                if (((Activity) context).getCurrentFocus() != null)
                    manager.hideSoftInputFromWindow(((Activity) context).getCurrentFocus()
                            .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    
        private void checkToastResult() {
            if (toast != null) {
                toast.setText("没有搜索结果");
                toast.setDuration(Toast.LENGTH_SHORT);
            } else {
                toast = Toast.makeText(context, "没有搜索结果", Toast.LENGTH_SHORT);
            }
            toast.show();
        }
    
        private void firstSearch() {
            searchList.clear();
            for (int i = 0; i < list.size(); i++) {
                try {
                    Class<?> clazz = list.get(i).getClass();
                    if (className.equals(clazz.getName())) {
                        Field field = clazz.getDeclaredField(attrName);
                        field.setAccessible(true);
                        String title = (String) field.get(list.get(i));
                        if (!TextUtils.isEmpty(title) && title.contains(editText.getText().toString())) {
                            searchList.add(i);
                        }
                    }
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            if (searchList.size() == 0) {
                checkToastResult();
                return;
            }
            searchCursor = 0;
            recyclerView.smoothScrollToPosition(searchList.get(searchCursor));
        }
    
        private void searchViewSmaller() {
            largeLayout.setVisibility(View.INVISIBLE);
            float scaleBig = (float) largeLayout.getMeasuredWidth() / smallLayout.getMeasuredWidth();
            ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(animView, "scaleX", scaleBig, 1f);
            int translateX = largeLayout.getMeasuredWidth() / 2 - smallLayout.getMeasuredWidth() / 2;
            ObjectAnimator translateAnim = ObjectAnimator.ofFloat(animView, "translationX", -translateX, 0);
            AnimatorSet animSet = new AnimatorSet();
            animSet.play(scaleAnim).with(translateAnim);
            animSet.setDuration(500);
            animSet.start();
            animSet.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
    
                }
    
                @Override
                public void onAnimationEnd(Animator animator) {
                    smallLayout.setVisibility(View.VISIBLE);
                }
    
                @Override
                public void onAnimationCancel(Animator animator) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animator) {
    
                }
            });
        }
    
        private void searchViewLarger() {
            smallLayout.setVisibility(View.INVISIBLE);
            float scaleBig = (float) largeLayout.getMeasuredWidth() / smallLayout.getMeasuredWidth();
            ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(animView, "scaleX", 1f, scaleBig);
            int translateX = largeLayout.getMeasuredWidth() / 2 - smallLayout.getMeasuredWidth() / 2;
            ObjectAnimator translateAnim = ObjectAnimator.ofFloat(animView, "translationX", 0, -translateX);
            AnimatorSet animSet = new AnimatorSet();
            animSet.play(scaleAnim).with(translateAnim);
            animSet.setDuration(500);
            animSet.start();
            animSet.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
    
                }
    
                @Override
                public void onAnimationEnd(Animator animator) {
                    largeLayout.setVisibility(View.VISIBLE);
                }
    
                @Override
                public void onAnimationCancel(Animator animator) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animator) {
    
                }
            });
        }
    
        public void freshList(List<Object> list) {
            this.list.clear();
            this.list.addAll(list);
        }
    }
    public class TopLayoutManager extends LinearLayoutManager {
    
        public TopLayoutManager(Context context) {
            super(context);
        }
    
        public TopLayoutManager(Context context, int orientation, boolean reverseLayout) {
            super(context, orientation, reverseLayout);
        }
    
        public TopLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
            RecyclerView.SmoothScroller smoothScroller = new TopSmoothScroller(recyclerView.getContext());
            smoothScroller.setTargetPosition(position);
            startSmoothScroll(smoothScroller);
        }
    
        private static class TopSmoothScroller extends LinearSmoothScroller {
    
            TopSmoothScroller(Context context) {
                super(context);
            }
    
            @Override
            public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
                return DensityHelp.dip2px(App.getApplication(), 138) - viewStart;
            }
        }
    }

    布局

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 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="wrap_content"
        android:layout_marginTop="88dp"
        tools:showIn="@layout/study_plan_layout">
    
        <android.support.v7.widget.CardView
            android:id="@+id/animView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_margin="10dp"
            android:background="@color/white"
            app:cardElevation="6dp">
    
            <View
                android:layout_width="35dp"
                android:layout_height="44dp" />
        </android.support.v7.widget.CardView>
    
        <android.support.v7.widget.CardView
            android:id="@+id/smallLayout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_margin="10dp"
            app:cardElevation="6dp">
    
            <RelativeLayout
                android:layout_width="35dp"
                android:layout_height="44dp">
    
                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:src="@drawable/icon_search_pages" />
            </RelativeLayout>
        </android.support.v7.widget.CardView>
    
        <android.support.v7.widget.CardView
            android:id="@+id/largeLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:visibility="invisible"
            app:cardElevation="6dp">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="44dp">
    
                <ImageView
                    android:id="@+id/close"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:src="@drawable/classsearch_icon_close" />
    
                <ImageView
                    android:id="@+id/next"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_toLeftOf="@id/close"
                    android:src="@drawable/classsearch_icon_next" />
    
                <ImageView
                    android:id="@+id/previous"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerVertical="true"
                    android:layout_toLeftOf="@id/next"
                    android:src="@drawable/classsearch_icon_previous" />
    
                <EditText
                    android:id="@+id/editText"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_alignBottom="@id/previous"
                    android:layout_alignTop="@id/previous"
                    android:layout_marginLeft="10dp"
                    android:layout_toLeftOf="@id/previous"
                    android:background="@drawable/search_bg"
                    android:hint="输入搜索内容"
                    android:paddingLeft="5dp"
                    android:singleLine="true"
                    android:textColor="@color/c333333"
                    android:textColorHint="@color/c999999"
                    android:textSize="14sp" />
            </RelativeLayout>
        </android.support.v7.widget.CardView>
    </RelativeLayout>

    调用

    //初始化
    TopLayoutManager layoutManager = new TopLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    FloatSearchView searchView = new FloatSearchiew(this, recyclerView, largeLayout, smallLayout, animView, "com.xuehu365.xuehu.model.CourseDetail", "lessonTitle"); 
    searchView.init();
    //刷新列表
    searchView.freshList(list);
    <include layout="@layout/study_plan_search_layout" />

    firstSearch方法中这一段

    Class<?> clazz = list.get(i).getClass();
    if (className.equals(clazz.getName())) {
        Field field = clazz.getDeclaredField(attrName);
        field.setAccessible(true);
        String title = (String) field.get(list.get(i));
        if (!TextUtils.isEmpty(title) && title.contains(editText.getText().toString())) {
            searchList.add(i);
        }
    }

    如果实体不同,修改className,和attrName即可

    高亮就不做了,adapter.notify。。

  • 相关阅读:
    asp.net六大对象
    python学习之类和实例的属性;装饰器@property
    第一次写博客,不知道写什么,就随便写一点咯
    Bash脚本编写初体验
    python学习之参数传递
    2016.9.30词法分析程序 108
    实验三 108
    10.28实验二 108
    词法分析实验报告 108
    组合数据类型练习,综合练习 108
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/8316560.html
Copyright © 2020-2023  润新知