Android listview to achieve rapid query A-Z (simulation of some weather Sohu, Netease and other weather forecasts)

Source: Internet
Author: User

First, let's look at some application views:

This application is cool. We can find the desired city and implement weather query and subscription. however, I want to raise my opinion here. This error is obvious. You use I to prompt at the beginning of city J, and J has passed it, it seems that NetEase is better. don't talk about it.

First, we need to implement the view prompt on the right. here we want to customize it. Here we refer to others.

Code snippet:

Public class mysidebar extends view {private textview; // display box private Boolean showbkg = false; // touch event ontouchingletterchangedlistener; // 26 letters public static string [] B = {"#", "A", "B", "C", "D", "E ", "F", "g", "H", "I", "J", "k", "L", "M", "n", "O ", "P", "Q", "r", "S", "T", "U", "V", "W", "X", "Y ", "Z"}; int choose =-1; // select paint = new paint (); // custom View It is best to specify the three constructors public mysidebar (context, attributeset attrs, int defstyle) {super (context, attrs, defstyle);} public mysidebar (context, attributeset attrs) {super (context, attrs);} public mysidebar (context) {super (context);}/*** override this method */protected void ondraw (canvas) {super. ondraw (canvas); // obtain the focus to change the background color. if (showbkg) {canvas. drawcolor (color. parsecolor ("#40000000");} int Hei Ght = getheight ()-30; // get the corresponding height int width = getwidth (); // get the corresponding width int singleheight = height/B. length; // obtain the height of each letter for (INT I = 0; I <B. length; I ++) {paint. setcolor (color. black); // paint. setcolor (color. white); paint. settypeface (typeface. default_bold); paint. setantialias (true); paint. settextsize (20); // select the status if (I = choose) {paint. setcolor (color. parsecolor ("# 3399ff"); paint. setfakeboldtext (true);} // X sit Equal to the middle-half of the string width. float xpos = width/2-paint. measuretext (B [I])/2; float ypos = singleheight * I + singleheight; canvas. drawtext (B [I], xpos, ypos, paint); paint. reset (); // reset the paint brush }}@ overridepublic Boolean dispatchtouchevent (motionevent event) {final int action = event. getaction (); Final float y = event. gety (); // click the Y coordinate final int oldchoose = choose; Final ontouchingletterchangedlistener listener = ontouchi Ngletterchangedlistener; Final int c = (INT) (y/getheight () * B. length); // click the proportion of the total height occupied by Y coordinates * the length of the array B is equal to the number of clicked B. switch (Action) {Case motionevent. action_down: showbkg = true; If (oldchoose! = C & listener! = NULL) {If (C> 0 & C <B. length) {listener. ontouchingletterchanged (B [c]); // executes the ontouchingletterchanged event. choose = C; // option invalidate (); // refresh} break; Case motionevent. action_move: If (oldchoose! = C & listener! = NULL) {If (C> 0 & C <B. length) {listener. ontouchingletterchanged (B [c]); choose = C; invalidate () ;}} break; Case motionevent. action_up: showbkg = false; choose =-1; // invalidate (); textview. setvisibility (view. gone); break;} return true;} public void settextview (textview) {This. textview = textview;}/*** method for public externally ** @ Param ontouchingletterchangedlistener */Public void listener (ontouchingletterchangedlistener) {This. ontouchingletterchangedlistener = ontouchingletterchangedlistener;}/*** interface ** @ author coder **/public interface ontouchingletterchangedlistener {public void ontouchingletterchanged (string S );}}

The comments are very detailed. I 'd like to check them out.

Next we will implement the content on the home page.

I have been depressed for a long time when I saw this style. What can I do with it? I have done this before. Android
Resolve the conflict between scrollview and listview (tablelayout + scrollview ). So I thought of using listview + tableview, And I encountered a lot of problems. Later I used it in turn. I would like to sum up a sentence that the control did not learn well. If I learned it well, all of these problems can be solved, you have time to use these methods. perhaps the simplest implementation is "listview nested listview ".

There will certainly be a problem, that is, the problem of item display.

The following is the implementation code: (Declaration is a bit messy, but it is not difficult. I think you are OK)

Implement the listview adapter.

/***** Custom adapter ** @ author Zhangjia **/class myadapter extends baseadapter {private context; Public myadapter (context) {super (); this. context = context;} @ overridepublic int getcount () {return mysidebar. b. length; // return mysidebar. b. length ;}@ overridepublic object getitem (INT position) {// todo auto-generated method stubreturn NULL;} @ overridepublic long getitemid (INT position ){// Todo auto-generated method stubreturn 0;} @ overridepublic view getview (INT position, view convertview, viewgroup parent) {textview; If (convertview = NULL) {holder = new viewholder (); convertview = (linearlayout) layoutinflater. from (context ). inflate (R. layout. item, null); holder. textview = (textview) convertview. findviewbyid (R. id. TV _item); holder. listview = (listview) convertview. findviewbyid (R. id. lv_item); convertview. settag (holder);} else {holder = (viewholder) convertview. gettag ();} final string textvalue = mysidebar. B [position]; //... b... C // display the control holder. textview. setvisibility (view. visible); holder. listview. setvisibility (view. visible); If (position = 0) {holder. textview. settext ("current city");} else {holder. textview. settext (textvalue);} child = getlistview (textvalue); holder. listview. setadapte R (child); // set the style (width) setlistviewheightbasedonchildren (holder. listview); If (child. getcount () = 0) {// This control disappears if no value exists. Holder. textview. setvisibility (view. gone); holder. listview. setvisibility (view. gone);} holder. listview. setonitemclicklistener (New onitemclicklistener () {@ overridepublic void onitemclick (adapterview <?> Parent, view, int position, long ID) {// parent. getitematposition (position ). tostring (); according to the item prompt, toast is safe. maketext (mainactivity. this, parent. getitematposition (position ). tostring (), 1000 ). show () ;}}); Return convertview ;}}

The nested listview in listivew shows that we need to dynamically set the height of the ilistview for the listview.

/***** Dynamically set the height of the listview ** @ Param listview */Public void setlistviewheightbasedonchildren (listview) {listadapter = listview. getadapter (); If (listadapter = NULL) {return;} int totalheight = 0; For (INT I = 0; I <listadapter. getcount (); I ++) {view listitem = listadapter. getview (I, null, listview); listitem. measure (0, 0); totalheight + = listitem. getmeasuredheight ();} viewgroup. layoutparams Params = listview. getlayoutparams (); Params. height = totalheight + (listview. getdividerheight () * (listadapter. getcount ()-1); // Params. height + = 5; // If without this statement, the listview will be // A // little short // listview. getdividerheight () obtains the height occupied by separators between subitems. // Params. the height finally shows the required height for the entire listview. setlayoutparams (Params );}

In this way, the external listview will customize its own height based on the height of the sub-listview.

Call the code (ontouchingletterchangedlistener Interface)

@Overridepublic void onTouchingLetterChanged(String s) {overlay.setText(s);overlay.setBackgroundColor(Color.GRAY);overlay.setVisibility(View.VISIBLE);int position = arrayList.indexOf(s);lvMain.setSelection(position);}
@ Overridepublic void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); initview (); // The initial viewet_main.addtextchangedlistener (textwatcher); citymanager. initdata (); // create a database adapter = new myadapter (this); lvmain. setadapter (adapter); arraylist = new arraylist <string> (); For (INT I = 0; I <mysidebar. b. length; I ++) {arraylist. add (mysidebar. B [I]) ;}}

The above is the main implementation code.


Project display:


It seems to be a good deal. Recently I want to implement a complete weather project, so I will build a shelf first. Haha.

The code is above, so I will not explain it much. Another point I need to explain is that the data in it can be parsed through the weather forecast interface to obtain the corresponding city.

Parsing is a request, and parsing strings will not be said much, but I also need to make it clear that we want to query letters and get the Pinyin of the city. this is a headache, although pingyin4j already exists. jar, but what's more, the multiphoneme is not solved. To solve this problem, I took a lot of detours and used the translation interface to request WebService because Chinese place names are pinyin, although I know that I am wrong and smart, it is difficult to build a good shelf. Although I know that some remote locations do not have English, I am very depressed. finally, we solved the 80% problem. As for the solution, you will also know it if I don't say it.

Here I will upload city. DB. If you need to click the link to download

/*************************************** **************************************** **************************************** **********************/

Recently, with reference to other implementations, I think the above practices are very complicated and there is no need to use listview to nest listview. In fact, we can use listview to implement them completely, this is just to sit down and judge when getview returns a view. I will briefly introduce whether it is useful or not. In short, it is useful to me, haha. this is because the above implementation is troublesome.

First, we first create data:

public void setData() {list.add("A");listTag.add("A");for (int i = 0; i < 5; i++) {list.add("ANDROID" + i);}list.add("B");listTag.add("B");for (int i = 0; i < 5; i++) {list.add("IPHONE" + i);}list.add("C");listTag.add("C");for (int i = 0; i < 5; i++) {list.add("WINDOW" + i);}

The purpose of this operation is to allow us to specify an item for self-operation when the listview is displayed.

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = convertView;if (listTag.contains(getItem(position))) {view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null);} else {view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null);}TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);textView.setText(getItem(position));return view;}

It is also easy to understand, because we have marked the data during setdata, so we can display the corresponding style in the specified row.

Result style:


The effect is similar to the above. I feel that this implementation is much more convenient, so we recommend that you use this method, but the above method is not complex, it is OK when the listview is displayed.


If there are any deficiencies, leave a message to indicate,

If you want source code, please leave your email. Thanks for you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.