搜尋此網誌

2015年10月10日 星期六

【Android】實作RecyclerView + ToolBar + SearchView

compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'com.android.support:recyclerview-v7:23.1.0'

res/menu:

在ToolBar新增一個搜尋圖案的按鈕
<item
        android:id="@+id/search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="collapseActionView|ifRoom" />

res/layout:

RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"/>

</FrameLayout>

MainLayout:
content_main指的就是recyclerview
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.example.searchview.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"/>

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main"/>

    <!--<include layout="@layout/FAB/">-->

</android.support.design.widget.CoordinatorLayout>

MainActivity:

onCreate
//Toolbar
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //預設資料
        availableLocales = new ArrayList<>();
        for (Locale l : Locale.getAvailableLocales()) {
            availableLocales.add(l.getDisplayName());

        }

        //RecyclerView
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        mRecyclerView.setHasFixedSize(true);

        //線性布局
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));


        mAdapter = new LanguageAdapter(availableLocales);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

RecyclerView布局Manager有三種:
  1. 線性佈局:mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
  2. 格狀佈局:mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));
  3. 瀑布佈局(縱向或橫向):mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL));  //HORIZONTAL
  • 設定view為預設動畫:mRecyclerView.setItemAnimator(new DefaultItemAnimator()); 
    • 在adapter使用以下函數,再搭配handler postdelay,可有動畫產生。
    • notifyItemChanged(int)
      notifyItemInserted(int) 
      notifyItemRemoved(int)
      notifyItemMoved(int, int)
      notifyItemRangeChanged(int, int)
      notifyItemRangeInserted(int, int)
      notifyItemRangeRemoved(int, int)
      
    • int為position位址

Adapter & ViewHolder:

private class LanguageAdapter extends RecyclerView.Adapter<ViewHolder> {

        private List<String> mLocales;

        private LanguageAdapter(List<String> mLocales) {
            this.mLocales = mLocales;
            notifyDataSetChanged();
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            TextView tv = (TextView) LayoutInflater.from(parent.getContext())
                    .inflate(android.R.layout.simple_list_item_1, parent, false);

            return new ViewHolder(tv);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.mTextView.setText(mLocales.get(position));
        }

        @Override
        public int getItemCount() {
            return mLocales.size();
        }

    }

    private static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView mTextView;

        public ViewHolder(TextView v) {
            super(v);
            mTextView = v;
        }
    }

Menu

onCreateOptionsMenu
設定當Search按鈕觸發後的動作,在這裡設定當,搜尋列輸入文字時,立刻判斷預設資料是否包含收尋文字,並透過adapter作即時更新→notifyDatachanged()。
getMenuInflater().inflate(R.menu.menu_main, menu);

        final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                mRecyclerView.setAdapter(new LanguageAdapter(OnFilter(availableLocales, newText)));
                return true;
            }
        });
        return true;

判斷輸入文字method,回傳List形態結果
//判斷輸入文字
    private List<String> OnFilter(List<String> filterLocales, String text) {
        String search = text.toLowerCase();

        final List<String> filtered = new ArrayList<>();

        for (String info : filterLocales) {
            final String localeName = info.toLowerCase();
            if (localeName.contains(search)) {
                filtered.add(localeName);
            }
        }
        return filtered;
    }

結果示意圖

2015年10月7日 星期三

【Design Pattern】


策略模式
定義了演算法家族,個別封裝起來,讓他們之間可以互相替換,此模式讓演算法的變動,不會影響到使用演算法的程式。
設計守則
  1. 找出程式中可能需要更動之處,把它們獨立出來,不要和那些不需要更動的程式碼混在一起。
    換句話說:
    把會變動的部份取出並封裝起來,以便以後可以輕易地擴充此部分,而不影響不需要更動的其他部分。
  2. 寫程式是針對介面而寫,而不是針對實踐方式而寫。
  3. 多用合成,少用繼承。



觀察者模式
定義了物件之間的一對多關係,如此一來,當一個物件改變狀態,其他相依者都會收到通知並自動更新。
  1. 設計時,盡量讓需要互動的元件之間關係鬆綁。