当前位置: 代码迷 >> Android >> Android归类列表菜单实现
  详细解决方案

Android归类列表菜单实现

热度:3   发布时间:2016-04-28 02:19:48.0
Android分类列表菜单实现

菜单功能是点击按钮弹出分类菜单

看看效果图


先说一下实现原理,弹出菜单采用的是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


源码下载








  相关解决方案