搜尋此網誌

顯示具有 ListView 標籤的文章。 顯示所有文章
顯示具有 ListView 標籤的文章。 顯示所有文章

2015年8月21日 星期五

【Android】實作SearchView / Search widget

紀錄一下
http://www.mysamplecode.com/2012/07/android-listview-custom-layout-filter.html
http://stackoverflow.com/questions/17720481/how-could-i-filter-the-listview-using-baseadapter
http://stackoverflow.com/questions/5713653/how-to-get-the-events-of-searchview-in-android
http://www.tutorialsbuzz.com/2014/08/filter-custom-listviewbaseadapter.html
--------------------------------------------------------

2015/08/21 22:54 整理
http://www.mysamplecode.com/2012/11/android-expandablelistview-search.html
http://www.cnblogs.com/over140/archive/2010/11/25/1887892.html
看得不少資料  感覺大部分都是需要 extends Filter來實作過濾listview的search功能,但感覺好像太複雜了,對我來說...
今天試了另一種方法,code比較簡潔,原理和上面的都差不多,也是想要的結果。就分享大概的步驟(http://developer.android.com/training/search/setup.html),如下:

res/menu/menu.xml
新增search item
<item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search"
        android:imeOptions="actionSearch"
        android:inputType="textCapWords"
        android:title="search"
        android:orderInCategory="90"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView"/>
其中
  • orderInCategory="90" 
    • 因為仍有其他menu item,排在Search右邊,所以先設90(由左至右;數字由小至大)
  • ifRoom 只要actionbar有空間,item就會顯示出來。
  • collapseActionView item使用時會展開,不用時會縮起來。
MainActivity
在畫面上顯示Menu item,在onCreateOptionsMenu的function 加上
getMenuInflater().inflate(R.menu.menu_main, menu);
確保search item會出現在menu上,但這時候search還是一樣沒有功能,需要繼續定義Search View的行為。

res/xml/searchable.xml
這步蠻重要,沒加這個,害我白做工好幾回。
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
            android:label="@string/msg_search"
            android:hint="@string/msg_search_help"/>
參考網路上的解釋:
一個Searchable Configuration至少包含一個android:label,其屬性要和你的 Android manifest(Android清單)中 <application>或<activity>元素的android:label屬性具有相同的值。

AndroidMainifest.xml
<meta-data
     android:name="android.app.searchable"
     android:resource="@xml/searchable" />
定義meta-data告知應用程式可以到res/xml/searchable.xml找到他。
<intent-filter>
     <action android:name="android.intent.action.SEARCH"/>
</intent-filter>
宣告activity須接受 action_SEARCH intent

MainActivity
SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
通過調用setSearchableInfo(SearchableInfo)方法來關聯搜索配置(the searchable configuration )和SearchView:

通過調用getSearchableInfo()方法可從已創建的可搜索的XML配置文件( the searchable configuration XML file)中獲得SearchableInfo對象。 

當可搜索的配置(searchable configuration)正確地與你的SearchView 相關聯時,用戶提交一個搜索查詢後,SearchView可以通過ACTION_SEARCH intent,啟動一個 activity。現在,你需要一個可以篩選(filter)這個intent和處理搜索查詢的活動。



最後和上面網頁的例子都有些不一樣。
ViewItemAdapter

private LayoutInflater mInflater;
    ArrayList<AirSiteObject> data;
    ArrayList<AirSiteObject> oldData;

    public ViewItemAdapter(Context view, ArrayList<AirSiteObject> arrayList) {
        mInflater = LayoutInflater.from(view);
        data = arrayList;
        oldData = new ArrayList<AirSiteObject>();
        oldData.addAll(data);
    }

data 是放置 listview的layout,過濾後的結果也用它呈現。
olddata 放置原本的資料。

額外增加兩個method
public void setSearchPattern(String pattern) {
        filterListByPattern(pattern.trim());
        this.notifyDataSetChanged();
    }

    private void filterListByPattern(String searchPattern) {
        data.clear();
        for (AirSiteObject info : oldData) {
            boolean add = true;
            do {
                if (searchPattern == null || searchPattern.equals("")) {
                    break;
                }
                if (info.getSiteName().contains(searchPattern)) {
                    break;
                }
                if (info.getCounty().contains(searchPattern)) {
                    break;
                }
                add = false;
            } while (false);
            if (add) {
                data.add(info);
            }
        }
    }

註:過濾的是中文,且資料內不可能會有空格產生,所以先用trim()把空格都濾掉。
  • 當search pattern是空的或是null時,就等於呈現的是原始資料。
  • 當pattern過濾條件符合,就加進來。

MainActivity/OnCreateOptionMenu
增加setOnQueryTextListener,但為了美觀,把整個method都show出來。

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);

        SearchManager searchManager = (SearchManager)getSystemService(Context.SEARCH_SERVICE);
        final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                mAdapter.setSearchPattern(s);
                return true;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }

其他res內的小bug改一改,應該就可以跑了。

先記錄到這邊,希望下次使用到這個功能,我才能看得懂在寫什麼。


ref: http://developer.android.com/training/search/setup.html

為了讓code版型不要跑掉,光這樣就花了1個半小時在寫這篇,累~

【Android】ListView進階版 --- RecyclerView

先記錄  有時間再看
http://lp43.blogspot.tw/2014/08/recyclerviewandroid-studio.html
--------------------------------------------------------------------------------
2015/10/10更新

詳細實作過程
【Android】實作RecyclerView + ToolBar + SearchView



2014年11月18日 星期二

【Android】sorting listview

ref:sorting listview in android

public class Team {
   private int points;
   private String name;

public Team(String n, int p) {
    name = n;
    points = p;
}

public int getPoints() {
    return points;
}

public String getName() {
    return name;
}

public static void main(String[] args) {
    List<Team> lteams = new ArrayList<Team>();

    lteams.add(new Team("FC Barcelona", 0));
    lteams.add(new Team("Arsenal FC", 2));
    lteams.add(new Team("Chelsea", 3));

    Collections.sort(lteams, new MyComparator());

    for (Team lteam : lteams) {
        System.out.println(lteam.name + ": " + lteam.points + " points");
    }
}
}
class MyComparator implements Comparator<Team> {
@Override
public int compare(Team o1, Team o2) {
    if (o1.getPoints() > o2.getPoints()) {
        return -1;
    } else if (o1.getPoints() < o2.getPoints()) {
        return 1;
    }
    return 0;
}}
Output:
Chelsea: 3 points
Arsenal FC: 2 points
FC Barcelona: 0 points

2014年11月3日 星期一

【Android】Refresh Listview ?

ref:http://stackoverflow.com/questions/2250770/how-to-refresh-android-listview




I want to refresh an Android ListView after adding/deleting dynamic data.
Can any one tell me how to achieve this?

 Method
  1. Call notifyDataSetChanged() on your Adapter object once you've modified the data in that adapter.  
  2. Also you can use this:
    myListView.invalidateViews();