菜单功能是点击按钮弹出分类菜单
看看效果图
先说一下实现原理,弹出菜单采用的是Fragment实现,很方便且高效,上面的三个按钮是RadioButton。
新建一个项目FragmentMenu
主界面activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RadioGroup android:id="@+id/group" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <RadioButton android:id="@+id/kind" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/selector_radio_back" android:button="@null" android:text="分类 >" android:gravity="center" android:textSize="18sp" /> <TextView android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:background="@color/lightgray" /> <RadioButton android:id="@+id/distance" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/selector_radio_back" android:button="@null" android:gravity="center" android:text="范围>" android:textSize="18sp" /> <TextView android:layout_width="2dp" android:layout_height="match_parent" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:background="@color/lightgray" /> <RadioButton android:id="@+id/sort" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:background="@drawable/selector_radio_back" android:button="@null" android:gravity="center" android:text="排序 >" android:textSize="18sp" /> </RadioGroup> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/lightgray" /> <LinearLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" /> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
布局文件我这里说一下,RadioGroup里面是RadioButton,使用这个主要是为了控制选中按钮背景色,使用RadioGroup之后就不必在代码中手动设置选中按钮背景色。紧接着的一个空白的LinearLayout,它是个容器,后面的Fragment就是装载这个里面的。下面的是一个ListView,在这个例子中我没有使用它。
selector_radio_back.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@android:color/white" android:state_checked="false"/> <item android:drawable="@color/lightgray" android:state_checked="true"/> </selector>
看一下MainActivity的主要代码
/** * 初始化控件 */ private void init() { // TODO Auto-generated method stub group = (RadioGroup) findViewById(R.id.group); kindBtn = (RadioButton) findViewById(R.id.kind); kindBtn.setOnClickListener(this); distanceBtn = (RadioButton) findViewById(R.id.distance); distanceBtn.setOnClickListener(this); sortBtn = (RadioButton) findViewById(R.id.sort); sortBtn.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.kind: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, kindFragment).commit(); fragment = kindFragment; break; case R.id.distance: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, distanceFragment) .commit(); fragment = distanceFragment; break; case R.id.sort: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, sortFragment).commit(); fragment = sortFragment; break; } }
在OnClick方法中把Fragment给加载出来,你在主界面所要做的几乎就是这么多,后面的菜单点击事件就完全的交给各个Fragment来实现,这样做各个Fragment之间结构泾渭分明,不易出错,也易于以后的维护。
MainActivity全部代码
package com.example.fragmentmenu; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.Toast; public class MainActivity extends FragmentActivity implements OnClickListener { private RadioGroup group; private RadioButton kindBtn, distanceBtn, sortBtn; private KindFragment kindFragment; private DistanceFragment distanceFragment; private SortFragment sortFragment; private Fragment fragment; /** * 用于接收从Fragment中发送来的消息 */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case 0:// 分类发来的消息 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); getSupportFragmentManager().beginTransaction().remove(fragment) .commit(); fragment = null; group.clearCheck(); break; case 1:// 范围发来的消息 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); getSupportFragmentManager().beginTransaction().remove(fragment) .commit(); fragment = null; group.clearCheck(); break; case 2:// 排序发来的消息 Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); getSupportFragmentManager().beginTransaction().remove(fragment) .commit(); fragment = null; group.clearCheck(); break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); kindFragment = new KindFragment(); kindFragment.setHandler(handler); distanceFragment = new DistanceFragment(); distanceFragment.setHandler(handler); sortFragment = new SortFragment(); sortFragment.setHandler(handler); init(); } /** * 初始化控件 */ private void init() { // TODO Auto-generated method stub group = (RadioGroup) findViewById(R.id.group); kindBtn = (RadioButton) findViewById(R.id.kind); kindBtn.setOnClickListener(this); distanceBtn = (RadioButton) findViewById(R.id.distance); distanceBtn.setOnClickListener(this); sortBtn = (RadioButton) findViewById(R.id.sort); sortBtn.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.kind: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, kindFragment).commit(); fragment = kindFragment; break; case R.id.distance: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, distanceFragment) .commit(); fragment = distanceFragment; break; case R.id.sort: getSupportFragmentManager().beginTransaction() .replace(R.id.fragment_container, sortFragment).commit(); fragment = sortFragment; break; } } /** * 监控手机返回按键,如果此时Fragment存在就把它移除,不存在就直接关闭界面 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if (fragment != null) { getSupportFragmentManager().beginTransaction().remove(fragment) .commit(); fragment = null; group.clearCheck(); } else finish(); return true; } return super.onKeyDown(keyCode, event); } }
关于Activity与Fragment的数据交互,有很多中实现方式,我这里是使用了Handler来实现数据交互,在Fragment中处理完点击事件之后会将处理结果发送到MainActivity以便于MainActivity继续下面的操作(比如说给ListView赋值)。
看第一Fragment,也是这里面最复杂的一个Fragment、新建一个Fragment名字叫KindFragment。
package com.example.fragmentmenu; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public class KindFragment extends Fragment implements OnItemClickListener { private ListView listView, detailListView; private List<String> list = new ArrayList<String>(), detaillist = new ArrayList<String>(); private KindAdapter listAdapter, detailAdapter; private Map<String, Integer> map = new HashMap<String, Integer>(); //用于保存选中的列表索引值 private int listSelect = -1, detailSelect = -1; private Handler handler; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment_kind, null); initData(); init(view); return view; } /** * 初始化数据 */ private void initData() { // TODO Auto-generated method stub map.put("快餐", R.array.kind_kuaichan); map.put("中餐", R.array.kind_zhongchan); map.put("西餐", R.array.kind_xichan); if (list != null && list.size() > 0) list.clear(); for (Map.Entry entry : map.entrySet()) list.add(entry.getKey().toString()); } /** * 初始化控件 * * @param view */ private void init(View view) { // TODO Auto-generated method stub listView = (ListView) view.findViewById(R.id.kind_list); listAdapter = new KindAdapter(getActivity()); listAdapter.setList(list); listAdapter.setClickItem(listSelect); listView.setAdapter(listAdapter); listView.setOnItemClickListener(this); detailListView = (ListView) view.findViewById(R.id.kind_detil_list); detailAdapter = new KindAdapter(getActivity()); detailAdapter.setList(detaillist); detailAdapter.setClickItem(detailSelect); detailListView.setAdapter(detailAdapter); detailListView.setOnItemClickListener(this); } /** * 加载子列表数据 * * @param key * @return */ private boolean addDetailList(String key) { if (detaillist != null && detaillist.size() > 0) detaillist.clear(); String[] detailArray = getResources().getStringArray(map.get(key)); if (detailArray.length <= 0) return false; for (String str : detailArray) detaillist.add(str); return true; } /** * ListView点击事件 */ @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub if (parent.getId() == R.id.kind_list) { listAdapter.setClickItem(position); listAdapter.notifyDataSetChanged(); listSelect = position; detailSelect = -1; boolean hasDetail = addDetailList(list.get(position)); detailAdapter.setClickItem(-1); detailAdapter.notifyDataSetChanged(); if (!hasDetail)// 将点击结果发送到主界面 handler.obtainMessage(0, list.get(position)).sendToTarget(); } else if (parent.getId() == R.id.kind_detil_list) { detailAdapter.setClickItem(position); detailAdapter.notifyDataSetChanged(); detailSelect = position; //将点击结果发送到主界面 handler.obtainMessage(0, detaillist.get(position)).sendToTarget(); } } public void setHandler(Handler handler) { this.handler = handler; } }
这个Fragment在这个项目里是最复杂的Fragment,这也只是相对来说,从上面的代码看,它并不复杂,之所以说它最复杂是因为后面的两个Fragment更简单。相关代码我都有注释,需要特别提出的一点是在adapter中添加了一个方法用于设置选中列表项的颜色。
private int clickItem = -1;; public void setClickItem(int clickItem) { this.clickItem = clickItem; }
KindAdapter完整代码
package com.example.fragmentmenu; import java.util.List; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class KindAdapter extends BaseAdapter { private List<String> list; private LayoutInflater inflater; public KindAdapter(Context context) { inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { // TODO Auto-generated method stub return list == null ? 0 : list.size(); } public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list == null ? null : list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return list == null ? -1 : position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); convertView = inflater .inflate(R.layout.adapter_fragment_list, null); holder.text = (TextView) convertView .findViewById(R.id.adapter_kind_text); convertView.setTag(holder); } else holder = (ViewHolder) convertView.getTag(); if (position != clickItem) { convertView.setBackgroundColor(Color.WHITE); } else { convertView.setBackgroundColor(Color.LTGRAY); } holder.text.setText(list.get(position)); return convertView; } private int clickItem = -1;; public void setClickItem(int clickItem) { this.clickItem = clickItem; } class ViewHolder { TextView text; } }
看一下布局文件
adapter_fragment_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:orientation="horizontal" > <TextView android:id="@+id/adapter_kind_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginBottom="10dp" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:src="@drawable/corner_arrow" /> </RelativeLayout>
KindFragment布局文件
fragment_kind.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ListView android:id="@+id/kind_list" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.3" /> <ListView android:id="@+id/kind_detil_list" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.7" /> </LinearLayout>
很简单,只有两个ListView。
后面的两个Fragment实现方式与之类似,我直接把代码贴出来
DistanceFragment
package com.example.fragmentmenu; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public class DistanceFragment extends Fragment implements OnItemClickListener { private ListView listView; private KindAdapter listAdapter; private List<String> list = new ArrayList<String>(); private int listSelect = -1; private Handler handler; public void setHandler(Handler handler) { this.handler = handler; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment_distance, null); initData(); init(view); return view; } private void initData() { // TODO Auto-generated method stub if (list != null && list.size() > 0) list.clear(); for (int i = 100; i < 105; i++) list.add(String.valueOf(i)); } private void init(View view) { // TODO Auto-generated method stub listView = (ListView) view.findViewById(R.id.diatnce_list); listAdapter = new KindAdapter(getActivity()); listAdapter.setList(list); listAdapter.setClickItem(listSelect); listView.setAdapter(listAdapter); listView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub listAdapter.setClickItem(position); listAdapter.notifyDataSetChanged(); listSelect = position; handler.obtainMessage(1, list.get(position)).sendToTarget(); } }
fragment_distance.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/diatnce_list" android:layout_width="match_parent" android:layout_height="wrap_content" />
SortFragment
package com.example.fragmentmenu; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; public class SortFragment extends Fragment implements OnItemClickListener { private ListView listView; private KindAdapter listAdapter; private List<String> list = new ArrayList<String>(); private int listSelect = -1; private Handler handler; public void setHandler(Handler handler) { this.handler = handler; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment_sort, null); initData(); init(view); return view; } private void initData() { // TODO Auto-generated method stub if (list != null && list.size() > 0) list.clear(); for (int i = 0; i < 5; i++) list.add(String.valueOf(i)); } private void init(View view) { // TODO Auto-generated method stub listView = (ListView) view.findViewById(R.id.sort_list); listAdapter = new KindAdapter(getActivity()); listAdapter.setList(list); listAdapter.setClickItem(listSelect); listView.setAdapter(listAdapter); listView.setOnItemClickListener(this); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub listAdapter.setClickItem(position); listAdapter.notifyDataSetChanged(); listSelect = position; handler.obtainMessage(2, list.get(position)).sendToTarget(); } }
fragment_sort.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/sort_list" android:layout_width="match_parent" android:layout_height="wrap_content" />
相关资源colors.xml
<pre name="code" class="html"><resources> <color name="lightgray">#d3d3d3</color> </resources>
corner_arrow.9.png