`
不夜的星辰
  • 浏览: 89138 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ExpandableListView+gallery+自定义view

 
阅读更多

前段时间在网上看到一个ExpandableListView与gallery相关的例子,感觉做的很不错;自己借用过来做了些许修改,实现了gallery借助手势onFling()方法实现左右自动滑动并带动自定义的view:

 

package com.qiyi.test;


import java.util.Timer;
import java.util.TimerTask;

import com.qiyi.R;
import com.qiyi.view.FlowView;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;

public class QHomeActivity extends Activity {

	private ExpandableListView expandableListView;
	public String[] groups = new String[]{"一月影视","二月影视","三月影视","四月影视"};
	public String[][] childs = new String[4][2];
	public int[] tags = new int[]{0,0,0,0};//用来标示每个组展开与收缩
	public int[] galleryImage = new int[]{R.drawable.test1, R.drawable.test2,
			R.drawable.test3, R.drawable.test1, R.drawable.test2,
			R.drawable.test3, R.drawable.test1, R.drawable.test2,
			R.drawable.test3};
	private ExpandableAdapter adapter;
	private View headerView;
	private Gallery gallery;
	private GalleryAdapter galleryAdapter;
	private FlowView flowView;
	private Timer timer;
	private static final int MSG_SEND1 = 0;
	private static final int MSG_SEND2 = 1;
	private int index_flag_gallery = 0;//gallery滑动方向索引标志位 0:向右 1:向左
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.q_home);
		initView();
		timer = new Timer();
		timer.scheduleAtFixedRate(new MyTask(), 0, 5000);
	}
	private class MyTask extends TimerTask{
		@Override
		public void run() {
			if(index_flag_gallery == 0){
				
				handler.sendEmptyMessage(MSG_SEND1);
			}else{
				handler.sendEmptyMessage(MSG_SEND2);
			}
		}
	}
	Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MSG_SEND1://通过手势自动滑动gallery
				MotionEvent e1 = MotionEvent.obtain(SystemClock.uptimeMillis(),
						SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
						89.333336f, 265.33334f, 0);
				MotionEvent e2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
						SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
						300.0f, 238.00003f, 0);

				gallery.onFling(e1, e2, -1300, 0);
				break;
			case MSG_SEND2:
				MotionEvent e11 = MotionEvent.obtain(SystemClock.uptimeMillis(),
						SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
						300.0f, 238.00003f, 0);
				MotionEvent e22 = MotionEvent.obtain(SystemClock.uptimeMillis(),
						SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
						89.333336f, 265.33334f, 0);

				gallery.onFling(e11, e22, 1300, 0);
				break;

			default:
				break;
			}
		};
	};
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}
	private void initView(){
		expandableListView = (ExpandableListView) findViewById(R.id.expandableListView1);
		adapter = new ExpandableAdapter(this);
		headerView = LayoutInflater.from(this).inflate(R.layout.q_header_view, null);
		
		gallery = (Gallery) headerView.findViewById(R.id.home_gallery);
		galleryAdapter = new GalleryAdapter(this);
		gallery.setAdapter(galleryAdapter);
		
		flowView = (FlowView) headerView.findViewById(R.id.myView);
		flowView.setCount(galleryAdapter.getCount());
		
		gallery.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				flowView.setSeletion(position);
				if(position == 0){
					index_flag_gallery = 0;
				}else if(position == flowView.getCount()-1){
					index_flag_gallery = 1;
				}
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				// TODO Auto-generated method stub
				
			}
		});
		
		expandableListView.addHeaderView(headerView);
		expandableListView.setAdapter(adapter);
		
		//展开
		expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() {
			
			@Override
			public void onGroupExpand(int groupPosition) {
				tags[groupPosition] = 1;
				//只展开一项
				for(int i=0 ;i<groups.length;i++){
					if(groupPosition != i){
						expandableListView.collapseGroup(i);
					}
				}
			}
		});
		//收缩
		expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
			
			@Override
			public void onGroupCollapse(int groupPosition) {
				tags[groupPosition] = 0;
			}
		});
	}
	/**
	 * gallery adapter
	 * @author Administrator
	 *
	 */
	private class GalleryAdapter extends BaseAdapter{

		private Context context;
		public GalleryAdapter(Context ctx){
			this.context = ctx;
		}
		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return galleryImage.length;
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return galleryImage[position];
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.gallery_item, null);
			}
			ImageView imageView = (ImageView) convertView.findViewById(R.id.home_img);
			imageView.setImageResource(galleryImage[position]);
			return convertView;
		}
		
	}
	/**
	 * 二级下拉列表adapter
	 * @author Administrator
	 *
	 */
	private class ExpandableAdapter extends BaseExpandableListAdapter{

		private Context context;
		public ExpandableAdapter(Context ctx){
			this.context = ctx;
			for(int i = 0 ;i < 4;i++){
				for(int j = 0;j < 2;j++){
					childs[i][j] = "child" + i + "_" + j;
				}
			}
		}
		@Override
		public Object getChild(int groupPosition, int childPosition) {
			// TODO Auto-generated method stub
			return childs[groupPosition][childPosition];
		}

		@Override
		public long getChildId(int groupPosition, int childPosition) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			if(convertView == null){
				convertView = LayoutInflater.from(context).inflate(R.layout.child_item, null);
			}
			return convertView;
		}

		@Override
		public int getChildrenCount(int groupPosition) {
			// TODO Auto-generated method stub
			return childs[groupPosition].length;
		}

		@Override
		public Object getGroup(int groupPosition) {
			// TODO Auto-generated method stub
			return groups[groupPosition];
		}

		@Override
		public int getGroupCount() {
			// TODO Auto-generated method stub
			return groups.length;
		}

		@Override
		public long getGroupId(int groupPosition) {
			// TODO Auto-generated method stub
			return groupPosition;
		}

		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			GroupHolder groupHolder = null;
			if(convertView == null){
				groupHolder = new GroupHolder();
				convertView = LayoutInflater.from(context).inflate(R.layout.group_item, null);
				groupHolder.imageView = (ImageView) convertView.findViewById(R.id.tag_img);
				groupHolder.title = (TextView) convertView.findViewById(R.id.title_view);
				
				convertView.setTag(groupHolder);
			}else{
				groupHolder = (GroupHolder) convertView.getTag();
			}
			if(tags[groupPosition] == 0){
				groupHolder.imageView.setImageResource(R.drawable.list_indecator_button);
			}else{
				groupHolder.imageView.setImageResource(R.drawable.list_indecator_button_down);
			}
			groupHolder.title.setText(groups[groupPosition]);
			return convertView;
		}

		@Override
		public boolean hasStableIds() {
			// TODO Auto-generated method stub
			return true;
		}

		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {
			// TODO Auto-generated method stub
			return true;
		}
		class GroupHolder{
			ImageView imageView;
			TextView title;
		}
	}
}

 下面是自定义的view:

package com.qiyi.view;


import com.qiyi.R;

import android.R.integer;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class FlowView extends View{

	private int count;
	private float space,radius;
	private int point_normal_color,point_selected_color;
	//选中
	private int seleted = 0;
	
	public FlowView(Context context, AttributeSet attrs) {
		super(context, attrs);
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowViewStyle);
		
		count = a.getInteger(R.styleable.FlowViewStyle_count, 4);
		space = a.getDimension(R.styleable.FlowViewStyle_space, 9);
		radius = a.getDimension(R.styleable.FlowViewStyle_point_radius, 9);
		
		point_normal_color = a.getColor(R.styleable.FlowViewStyle_point_normal_color, 0x000000);
		point_selected_color = a.getColor(R.styleable.FlowViewStyle_point_seleted_color, 0xffff07);
		
		int sum = attrs.getAttributeCount();
		/*if(true){
			String str = "";
			for(int i=0;i<sum;i++){
				String name = attrs.getAttributeName(i);
				String value = attrs.getAttributeValue(i);
				str += "attr_name:" + name + ": " + value + "\n";
			}
		}*/
		a.recycle();
	}

	public void setSeletion(int index){
		this.seleted = index;
		invalidate();
	}
	public void setCount(int count){
		this.count = count;
		invalidate();
	}
	public int getCount(){
		return count;
	}
	public void next(){
		if(seleted < count - 1){
			seleted++;
		}else{
			seleted = 0;
		}
		invalidate();
	}
	public void previous(){
		if(seleted > 0){
			seleted --;
		}else{
			seleted = count - 1;
		}
		invalidate();
	}
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		float width = (getWidth() - ((radius*2*count) + (space*(count-1))))/2.f;
		for(int i=0;i < count;i++){
			if(i == seleted){
				paint.setColor(point_selected_color);
			}else{
				paint.setColor(point_normal_color);
			}
			canvas.drawCircle(width + getPaddingLeft() + radius + i
					* (space + radius + radius), getHeight() / 2, radius, paint);
		}
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		//裁定绘制图样的区域
		setMeasuredDimension(measureWith(widthMeasureSpec), measureHeight(heightMeasureSpec));
	}
	private int measureWith(int measureSpec){
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);
		if(specMode == MeasureSpec.EXACTLY){
			result = specSize;
		}else{
			result = (int)(getPaddingLeft()+getPaddingRight()+(count*2*radius)+(count-1)*radius+1);
		}
		return result;
	}
	private int measureHeight(int measureSpec) {
		int result = 0;
		int specMode = MeasureSpec.getMode(measureSpec);
		int specSize = MeasureSpec.getSize(measureSpec);

		if (specMode == MeasureSpec.EXACTLY) {
			result = specSize;
		} else {
			result = (int) (2 * radius + getPaddingTop() + getPaddingBottom() + 1);
			if (specMode == MeasureSpec.AT_MOST) {
				result = Math.min(result, specSize);
			}
		}
		return result;
	}
}

 用于指定自定义view的属性的xml文件(values目录下):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FlowViewStyle">
      <attr name="count" format="integer"/>
      <attr name="space" format="dimension"/>
      <attr name="point_size" format="dimension"/>
      <attr name="point_seleted_color" format="color|reference"/>
      <attr name="point_normal_color" format="color|reference"/>
      <attr name="point_radius" format="dimension"/>
    </declare-styleable>
</resources>

 选择样式文件(values目录下):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <drawable name="transparent">#00000000</drawable>
</resources>

 

<?xml version="1.0" encoding="utf-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/transparent" android:state_expanded="true"></item>
    <item android:drawable="@drawable/transparent"></item>
</selector>

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
    <include layout="@layout/title_view"/>
    <ExpandableListView android:id="@+id/expandableListView1" 
                        android:layout_height="wrap_content" 
                        android:layout_width="fill_parent"
                        android:groupIndicator="@drawable/tag_but_background">
    </ExpandableListView>
    
</LinearLayout>

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res/com.qiyi"

    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

   <Gallery android:id="@+id/home_gallery"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:spacing="5dip"/>
   <LinearLayout android:id="@+id/linearLayout1" 
                 android:layout_width="fill_parent" 
                 android:layout_height="wrap_content" 
                 android:layout_gravity="bottom"
                 android:orientation="vertical"
                 android:background="#65000000">
       <TextView android:text="好影视,一网打尽" 
                 android:id="@+id/textView1" 
                 android:layout_width="wrap_content" 
                 android:layout_height="wrap_content"
                 android:layout_gravity="center"
                 android:layout_marginBottom="5dip"
                 android:layout_marginTop="5dip"
                 android:textColor="#ffffff"
                 android:textSize="18dip">
       </TextView>
       <com.qiyi.view.FlowView
         android:id="@+id/myView"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="5dip"
         app:count="4"
         android:gravity="center"
         app:point_normal_color="#45000000"
         app:point_radius="3dip"
         app:point_seleted_color="#ffffff"
         app:point_size="5dip"
         app:space="10dip">
       </com.qiyi.view.FlowView>
   </LinearLayout>
</FrameLayout>

 

  • 大小: 25.3 KB
分享到:
评论
2 楼 tianshengwo123 2012-06-12  
楼主可以把整个工程源码传上来么?
1 楼 duxiux 2012-03-23  
楼主分享下源码吧

相关推荐

    Drawerlayout+ExpandableListView+,Fragment+Viewpager

    本资源在底层Drawerlayout中嵌套了ExpandableListView,同时兼具Fragment+Viewpager的功能。ExpandableListView自定义了group和item图片和文字,看起来效果还凑合

    利用dialog弹出 二级下拉列表 ExpandableListView+DialogLI

    总的来说,"利用dialog弹出二级下拉列表 ExpandableListView+DialogLI"是一种有效且灵活的实现方式,它结合了`Dialog`的弹窗功能和`ExpandableListView`的多级展示特性,为Android应用提供了丰富的交互体验。...

    Android 利用dialog弹出 二级下拉列表 ExpandableListView+DialogLI

    Android 利用dialog弹出 二级下拉列表 ExpandableListView+DialogLI。 利用dialog和ExpandableListView实现的一个弹出二级菜单项,并进行了封装,可在activity和fragment中随意调用。简单实用,兼容性好。 二级列表

    expandablelistview+自定义adapter+listview字母排序

    在这个特定的示例中,“expandablelistview+自定义adapter+listview字母排序”是为了展示中国各个省市,并且通过字母对数据进行了排序,使得用户可以快速找到目标信息。 首先,我们要理解ExpandableListView的工作...

    Android ExpandableListView+PopupWindow+json

    在本项目"Android ExpandableListView+PopupWindow+json"中,这两个组件被巧妙地结合起来,以动态加载来自JSON数据源的信息。 `ExpandableListView`是一个可扩展的列表视图,允许用户展开和折叠各个组,每个组内...

    expandablelistview + gridview + 手势的新闻客户端

    为了使用`GridView`,我们需要创建自定义的`GridView`适配器,将数据绑定到每个单元格,并为每个单元格设置合适的点击事件。 再者,手势识别是移动应用中增强用户体验的重要技术。在这个新闻客户端中,手势识别可能...

    Android的ExpandableListView+CheckBox全选

    总结起来,"Android的ExpandableListView+CheckBox全选"涉及到的知识点有:`ExpandableListView`的使用,自定义适配器`ExpandableListAdapter`,`CheckBox`的事件监听,以及全选和反选功能的实现。通过以上步骤,...

    ExpandableListView+CheckBox多选功能

    在给定的“ExpandableListView+CheckBox多选功能”主题中,我们将探讨如何将这两个组件整合,创建一个既具有扩展性又支持多选操作的用户界面。 首先,我们需要理解`ExpandableListView`的基本工作原理。`...

    ExpandablelistView+swipeLayout实现的滑动删除效果

    "ExpandableListView+SwipeLayout实现的滑动删除效果"就是一个很好的示例,它结合了ExpandableListView的分组展开功能与SwipeLayout的侧滑删除机制,为用户提供了直观且高效的操作方式。下面将详细介绍这一技术实现...

    ExpandableListView+CheckBox+RadioButton

    3. **自定义适配器**:`ExpandableListView`需要一个`ExpandableListAdapter`来绑定数据。开发者可以根据需求定制适配器,实现自定义的视图和行为。 4. **事件监听**:`ExpandableListView`提供了`...

    Android Expandablelistview +CheckBox

    `ExpandableListView`不仅支持分组(Group)和子项(Child)的概念,还允许用户交互,比如点击展开或折叠分组,以及在子项中添加自定义视图,如`CheckBox`。`CheckBox`的引入使得用户可以进行多选操作,这对于数据...

    ExpandAbleListView+checkbox数组方式级联,点击选择顶部文本显示,可删除

    ExpandAbleListView+checkbox数组方式级联,外层列表可展开收起,内层列表使用checkbox多选框,点击之后可在顶部的gridlayout显示,顶部显示的选中与checkbox选中状态关联,点击顶部选中的item,可取消选中状态,...

    dialog弹出 二级下拉列表 ExpandableListView+Dialog

    为了在`Dialog`中使用`ExpandableListView`,我们需要创建一个自定义的`Dialog`类。首先,我们在布局文件中定义`ExpandableListView`,并设置必要的属性,如分隔线、背景颜色等。接着,我们需要创建一个适配器...

    ExpandableListView+SwipeItem

    在Android原生API中并没有直接提供滑动删除的支持,但可以通过自定义`ExpandableListView`的子项布局和手势检测来实现。当用户向左或向右滑动某个子项时,显示删除按钮或其他操作提示,然后响应用户的点击进行相应的...

    ExpandableListView实现购物车页面

    在Android应用开发中,"ExpandableListView实现购物车页面"是一个常见的需求,它涉及到用户界面设计、数据管理和交互。ExpandableListView是Android SDK提供的一种可扩展的列表视图,允许用户展示分组数据,每组内...

    expandablelistview自定义实现单选效果

    本教程将详细讲解如何自定义ExpandableListView,使其一级标题具有类似于RadioButton的单选效果。 首先,我们需要创建一个自定义的ExpandableListAdapter,这个适配器将负责处理数据绑定和视图的渲染。适配器的核心...

    Android实现自定义适配器的ExpandableListView示例.rar

    Android实现自定义适配器的ExpandableListView示例,准备一级列表中显示的数据:2个一级列表,分别显示"group1"和"group2",准备第一个一级列表中的二级列表数据:两个二级列表,分别显示"childData1"和"childData2",...

    自定义横向Expandablelistview

    标题“自定义横向Expandablelistview”指的就是这样一个需求:将原本垂直展示的ExpandableListView改为横向滚动,并且添加了动画效果,以提供更丰富的用户体验。 在这种自定义实现中,通常会用到RecyclerView,因为...

    自定义布局模仿ExpandableListView

    接下来,我们需要创建自定义的Adapter,它是连接数据源和View的关键。这个Adapter需要继承自ExpandableListAdapter,并覆盖其必要的方法,如`getGroupCount()`、`getChildCount()`、`getGroupView()`和`getChildView...

    自定义View模拟ExpandableListView效果

    然而,有时我们可能需要在没有ExpandableListView原生支持的场景下实现类似的效果,例如在自定义View中。本文将详细探讨如何通过自定义View来模拟ExpandableListView的功能。 首先,我们要理解ExpandableListView的...

Global site tag (gtag.js) - Google Analytics