漫谈android开发之菜单(一)
前言:
学习android断断续续也有一年半左右,但一直在学习,很少回顾以往的知识。所以我打算用业余时间来写一些这样总结性的文章,希望温故知新。
以下只是我个人的一些感悟和见解(当然会查证资料验证),难免有错误之处。所以如果有不同意见,十分欢迎留言交流,再次拜谢。
简介:
首先,此处的菜单不是Menu.它是各类菜单和导航的统称。这里包括了android的Menu、tab、slidingMenu、通过ViewPager和TitlePageIndicator的导航、自定义menu等等。
咱们可以定义,菜单布局=选项区+内容区。
选项区:
选项区基本有以下几种:
一,固定在屏幕顶部或者底部。
二,隐藏在屏幕边。
三,按下手机菜单键出现和隐藏。
(这里是应用重写了Menu键的响应,改用了自己的popwindow)
总的来说,选项区就是一些在排列上有组织的widget.
内容区
内容区大致可以分为两种:
一种是“一个容器型”。容器可以是一个view(通常是一个空的布局),然后每次内容改变时,通过LayoutInflater获取一个布局的实例化或者是通过findViewById获取一个widget,返回值是view,因此直接赋值或者addView都可以。
另一种是“多个容器型”。比如多个Activity,你没选择一项就跳转到另一个Activity.(tabActivity虽然addTab()时的setContent()方法可以传Intent,但实际上都是把每个Activity放入tabActivity局部中id为tabCotent的组件中显示,所以也可以认为是采用了“一个容器型”,虽然数据的传输上和多个Activity之间的传输一致。)
总的来说,内容区就是一个或多个可以往里面放View的容器。
从零开始实现这些菜单:
版本一:
用最简单的思维看,选项区的特点是有组织,然后普遍的做法是给选中的选项加上标识(win8风格就无须这个),这就还需要选项之间互斥。要实现这些,很简单,几个Button就可以搞定。
1,用LinearLayout把这些Button装起来。这里注意:LinearLayout的gravity只能作用于垂直当前方向的方向,即orientation为vertical的布局,layout_gravity="left"有效,layout_gravity="bottom"无效.我这里用一个LinearLayout将其挤压到底部。刚好这个LinearLayout用来放置内容区。布局如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <LinearLayout 3 android:layout_width="fill_parent" 4 android:layout_height="fill_parent" 5 android:orientation="vertical" 6 xmlns:android="http://schemas.android.com/apk/res/android"> 7 <LinearLayout 8 android:id="@+id/main_tabcontent" 9 android:layout_width="fill_parent" 10 android:layout_height="fill_parent" 11 android:layout_weight="1"/> 12 <LinearLayout 13 android:layout_width="fill_parent" 14 android:layout_height="70dp" 15 android:orientation="horizontal"> 16 <ImageButton 17 android:id="@+id/main_tab_wt" 18 android:layout_width="fill_parent" 19 android:layout_height="fill_parent" 20 android:layout_weight="1" 21 android:background="@drawable/main_tab_wt_1"/> 22 <ImageButton 23 android:id="@+id/main_tab_qz" 24 android:layout_width="fill_parent" 25 android:layout_height="fill_parent" 26 android:layout_weight="1" 27 android:background="@drawable/main_tab_qz_0"/> 28 <ImageButton 29 android:id="@+id/main_tab_yh" 30 android:layout_width="fill_parent" 31 android:layout_height="fill_parent" 32 android:layout_weight="1" 33 android:background="@drawable/main_tab_yh_0"/> 34 <ImageButton 35 android:id="@+id/main_tab_sc" 36 android:layout_width="fill_parent" 37 android:layout_height="fill_parent" 38 android:layout_weight="1" 39 android:background="@drawable/main_tab_home_0"/> 40 41 </LinearLayout> 42 43 </LinearLayout>
2,在OnClickListener中监听每个Button的点击,当一个Button被点击后,更改这些Button的背景实现互斥。然后每个Button对应的内容也在监听器中贴入View。
贴入布局的最简单方法是什么?当然是直接获取XML布局的实例了。代码如下(我写的逻辑部分临时给删了,请无视那些多余的import吧):
package com.zhihu.ui; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.zhihu.model.ObjectToXml; import com.zhihu.model.Question; import com.zhihu.model.QuestionHelper; import com.zhihu.model.WtAdapter; import com.zhihu.model.cache; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.Toast; import android.support.v4.app.NavUtils; public class MainActivity extends Activity implements OnClickListener{ private View wtView,qzView,scView,yhView; private ImageButton wtImage,qzImage,scImage,yhImage; private LayoutInflater layoutInflater; private LinearLayout tabContent; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViews(); initViews(); } private void initViews() { // TODO Auto-generated method stub wtImage.setOnClickListener(this); qzImage.setOnClickListener(this); scImage.setOnClickListener(this); yhImage.setOnClickListener(this); } private void findViews() { // TODO Auto-generated method stub //view of mainActivity layoutInflater = getLayoutInflater().from(this); tabContent = (LinearLayout) findViewById(R.id.main_tabcontent); wtImage = (ImageButton) findViewById(R.id.main_tab_wt); qzImage = (ImageButton) findViewById(R.id.main_tab_qz); scImage = (ImageButton) findViewById(R.id.main_tab_sc); yhImage = (ImageButton) findViewById(R.id.main_tab_yh); //获取布局的实例化 wtView = layoutInflater.inflate(R.layout.main_wt, null); qzView = layoutInflater.inflate(R.layout.main_qz, null); scView = layoutInflater.inflate(R.layout.main_sc, null); yhView = layoutInflater.inflate(R.layout.main_yh, null); //初始化为显示第一个选项的内容 tabContent.addView(wtView); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()){ case R.id.main_tab_wt: wtImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_wt_1)); qzImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_qz_0)); scImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_home_0)); yhImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_yh_0)); tabContent.removeAllViews(); tabContent.addView(wtView); break; case R.id.main_tab_qz: wtImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_wt_0)); qzImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_qz_1)); scImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_home_0)); yhImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_yh_0)); tabContent.removeAllViews(); tabContent.addView(qzView); break; case R.id.main_tab_sc: wtImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_wt_0)); qzImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_qz_0)); scImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_home_1)); yhImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_yh_0)); tabContent.removeAllViews(); tabContent.addView(scView); break; case R.id.main_tab_yh: wtImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_wt_0)); qzImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_qz_0)); scImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_home_0)); yhImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.main_tab_yh_1)); tabContent.removeAllViews(); tabContent.addView(yhView); break; } } }
到了这步,基本完成。注意一点,在别的布局文件中的widget,findViewById时需要确定使用谁的方法。即应该用view.findViewById()。
第一个版本基本OK,除去代码层面不说,功能上已经可以使用了。
肯定有朋友会问,那四个Button为啥不用RadioButton来实现互斥呢?这个是下一个版本的事了。敬请关注。