谷歌应用市场4

 

1.ViewPager的优化

1.屏幕适配

(1)用工具类把dp转换成px

(2)把dp写到dimens.xml中

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="list_item_title_size">16dp</dimen>
    <dimen name="list_item_loadmore_height">40dp</dimen>
    <dimen name="list_item_margin">9dp</dimen>
    <dimen name="home_picture_height">134dp</dimen>
    <dimen name="list_item_rating_height">14dp</dimen>
    <dimen name="app_detail_rating_margin">5dp</dimen>
</resources>


2.获取demens中数值

	public static int getDimens(int homePictureHeight) {
		return (int) getResource().getDimension(homePictureHeight);
	}


3.ViewPager的优化

(1)让ViewPager正常显示

(2)让ViewPager能无限切换(getCount(),   instantiateItem())

(3)让ViewPager一开始左右都能滑动

viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置   Integer.Max_Vlue/2

(4)仿照ListView复用缓存优化ViewPager(convertView)

public class HomePictureHolder extends BaseHolder<List<String>> {
	/* 当new HomePictureHolder()就会调用该方法 */
	private ViewPager viewPager;
	private List<String> datas;

	@Override
	public View initView() {
		viewPager = new ViewPager(UiUtils.getContext());
		viewPager.setLayoutParams(new AbsListView.LayoutParams(
				LayoutParams.MATCH_PARENT, UiUtils
						.getDimens(R.dimen.home_picture_height)));
		return viewPager;
	}

	/* 当 holder.setData 才会调用 */
	@Override
	public void refreshView(List<String> datas) {
		this.datas = datas;
		viewPager.setAdapter(new HomeAdapter());
		viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置   Integer.Max_Vlue/2
		 
	}
	 
	class HomeAdapter extends PagerAdapter {
		// 当前viewPager里面有多少个条目
		LinkedList<ImageView> convertView=new LinkedList<ImageView>();
		// ArrayList
		@Override
		public int getCount() {
			return	Integer.MAX_VALUE;
		}

		/* 判断返回的对象和 加载view对象的关系 */
		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			ImageView view=(ImageView) object;
			convertView.add(view);// 把移除的对象 添加到缓存集合中
			container.removeView(view);
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			int index=position%datas.size();
			ImageView view;
			if(convertView.size()>0){
				view=convertView.remove(0);
			}else{
				view= new ImageView(UiUtils.getContext());
			}
			bitmapUtils.display(view, HttpHelper.URL + "image?name="
					+ datas.get(index));
			container.addView(view); // 加载的view对象
			return view; // 返回的对象
		}

	}

}


 

4.使用HomeFragment

                  BaseListView listView=new BaseListView(UiUtils.getContext());
		HomePictureHolder holder=new HomePictureHolder();
		holder.setData(pictures);
		View contentView = holder.getContentView(); // 得到holder里面管理的view对象
		//contentView.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
		listView.addHeaderView(contentView); // 把holder里的view对象 添加到listView的上面


 

2.自动轮询

1.延迟执行当前任务(Uiutils)

	/**
	 * 延迟执行 任务
	 * @param run   任务
	 * @param time  延迟的时间
	 */
	public static void postDelayed(Runnable run, int time) {
		BaseApplication.getHandler().postDelayed(run, time); // 调用Runable里面的run方法
	}


2.取消当前任务(Uiutils)

/**
	 * 取消任务
	 * @param auToRunTask
	 */
	public static void cancel(Runnable auToRunTask) {
		BaseApplication.getHandler().removeCallbacks(auToRunTask);
	}


3.ViewPager自动轮播

/* 当 holder.setData 才会调用 */
	@Override
	public void refreshView(List<String> datas) {
		this.datas = datas;
		viewPager.setAdapter(new HomeAdapter());
		viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置   Integer.Max_Vlue/2
		viewPager.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					runTask.stop();   
					break;
				case MotionEvent.ACTION_CANCEL:  // 事件的取消
				case MotionEvent.ACTION_UP:
					runTask.start();
					break;
				}
				
				return false; // viewPager 触摸事件 返回值要是false  
			}
		});
		runTask = new AuToRunTask();
		runTask.start();
	}
	boolean flag;
	private AuToRunTask runTask;
	public class AuToRunTask implements Runnable{

		@Override
		public void run() {
			if(flag){
				UiUtils.cancel(this);  // 取消之前
				int currentItem = viewPager.getCurrentItem();
				currentItem++;
				viewPager.setCurrentItem(currentItem);
				//  延迟执行当前的任务
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public void start(){
			if(!flag){
				UiUtils.cancel(this);  // 取消之前
				flag=true;
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public  void stop(){
			if(flag){
				flag=false;
				UiUtils.cancel(this);
			}
		}
		
	}


4.总HomePictureHolder

public class HomePictureHolder extends BaseHolder<List<String>> {
	/* 当new HomePictureHolder()就会调用该方法 */
	private ViewPager viewPager;
	private List<String> datas;

	@Override
	public View initView() {
		viewPager = new ViewPager(UiUtils.getContext());
		viewPager.setLayoutParams(new AbsListView.LayoutParams(
				LayoutParams.MATCH_PARENT, UiUtils
						.getDimens(R.dimen.home_picture_height)));
		return viewPager;
	}

	/* 当 holder.setData 才会调用 */
	@Override
	public void refreshView(List<String> datas) {
		this.datas = datas;
		viewPager.setAdapter(new HomeAdapter());
		viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置   Integer.Max_Vlue/2
		viewPager.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					runTask.stop();   
					break;
				case MotionEvent.ACTION_CANCEL:  // 事件的取消
				case MotionEvent.ACTION_UP:
					runTask.start();
					break;
				}
				
				return false; // viewPager 触摸事件 返回值要是false  
			}
		});
		runTask = new AuToRunTask();
		runTask.start();
	}
	boolean flag;
	private AuToRunTask runTask;
	public class AuToRunTask implements Runnable{

		@Override
		public void run() {
			if(flag){
				UiUtils.cancel(this);  // 取消之前
				int currentItem = viewPager.getCurrentItem();
				currentItem++;
				viewPager.setCurrentItem(currentItem);
				//  延迟执行当前的任务
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public void start(){
			if(!flag){
				UiUtils.cancel(this);  // 取消之前
				flag=true;
				UiUtils.postDelayed(this, 2000);// 递归调用
			}
		}
		public  void stop(){
			if(flag){
				flag=false;
				UiUtils.cancel(this);
			}
		}
		
	}
	
	class HomeAdapter extends PagerAdapter {
		// 当前viewPager里面有多少个条目
		LinkedList<ImageView> convertView=new LinkedList<ImageView>();
		// ArrayList
		@Override
		public int getCount() {
			return	Integer.MAX_VALUE;
		}

		/* 判断返回的对象和 加载view对象的关系 */
		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			ImageView view=(ImageView) object;
			convertView.add(view);// 把移除的对象 添加到缓存集合中
			container.removeView(view);
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			int index=position%datas.size();
			ImageView view;
			if(convertView.size()>0){
				view=convertView.remove(0);
			}else{
				view= new ImageView(UiUtils.getContext());
			}
			bitmapUtils.display(view, HttpHelper.URL + "image?name="
					+ datas.get(index));
			container.addView(view); // 加载的view对象
			return view; // 返回的对象
		}

	}

}


 

3.MenuHolder创建

1.在FrameLayout中添加布局(MenuHolder返回一个View对象)

// 添加菜单
		fl_menu=(FrameLayout) findViewById(R.id.fl_menu);
		MenuHolder holder=new MenuHolder();
		//  之前已经登录过了
		//holder.setData(data)
		fl_menu.addView(holder.getContentView());


2.用户信息 UserInfo

 

/**
 * 用户信息
 * 
 * @author itcast
 * 
 */
public class UserInfo {
	private String name;
	private String url;
	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public UserInfo() {
		super();
	}

	public UserInfo(String name, String url, String email) {
		super();
		this.name = name;
		this.url = url;
		this.email = email;
	}

}


 3.布局

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true" >
	<!--ScollView 包裹的孩子 默认高度只能是包裹内容 
	 android:fillViewport="true"允许孩子是匹配父容器  -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <RelativeLayout
            android:id="@+id/photo_layout"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:background="@drawable/menu_icon_bg"
            android:paddingLeft="10dp"
            android:paddingRight="10dp" >

            <ImageView
                android:id="@+id/image_photo"
                android:layout_width="55dp"
                android:layout_height="55dp"
                android:background="@drawable/bg_photo"
                android:padding="5dip" />

            <ImageView
                android:id="@+id/image_over"
                android:layout_width="55dp"
                android:layout_height="55dp"
                android:src="@drawable/photo_over" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="55dp"
                android:layout_marginLeft="20dp"
                android:layout_toRightOf="@id/image_photo"
                android:gravity="center_vertical" >

                <TextView
                    android:id="@+id/user_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:singleLine="true"
                    android:text="@string/tv_user_name"
                    android:textColor="#2b2b2b"
                    android:textSize="18dp" />

                <TextView
                    android:id="@+id/user_email"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/user_name"
                    android:layout_marginTop="5dp"
                    android:singleLine="true"
                    android:text="@string/tv_user_email"
                    android:textColor="#7a7a7a"
                    android:textSize="14dp" />
            </RelativeLayout>
        </RelativeLayout>

        <!-- 4f4f4f -->

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/home_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_home"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_home" />

            <TextView
                android:id="@+id/tv_home"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_home"
                android:text="@string/tv_home"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/setting_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_setting"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_setting" />

            <TextView
                android:id="@+id/tv_setting"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_setting"
                android:text="@string/tv_setting"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/theme_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_theme"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_theme" />

            <TextView
                android:id="@+id/tv_theme"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_theme"
                android:text="@string/tv_theme"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/scans_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_scans"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_scans" />

            <TextView
                android:id="@+id/tv_scans"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_scans"
                android:text="@string/tv_scans"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/feedback_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_feedback"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_feedback" />

            <TextView
                android:id="@+id/tv_feedback"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_feedback"
                android:text="@string/tv_feedback"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/updates_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_updates"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_updates" />

            <TextView
                android:id="@+id/tv_updates"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_updates"
                android:text="@string/tv_updates"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/about_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_about"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_about" />

            <TextView
                android:id="@+id/tv_about"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_about"
                android:text="@string/tv_about"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />

        <RelativeLayout
            android:id="@+id/exit_layout"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@drawable/menu_item_bg"
            android:gravity="center_vertical"
            android:paddingLeft="15dp" >

            <ImageView
                android:id="@+id/ic_exit"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_exit" />

            <TextView
                android:id="@+id/tv_exit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:layout_toRightOf="@id/ic_exit"
                android:text="@string/tv_exit"
                android:textColor="#9b9b9b"
                android:textSize="18dp" />
        </RelativeLayout>

        <View
            android:layout_width="wrap_content"
            android:layout_height="1dp"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:background="#1a000000" />
    </LinearLayout>

</ScrollView>


 

4.Menu菜单&登录

 1.用户联网协议

public class UserProtocol extends BaseProtocol<UserInfo> {

	@Override
	public UserInfo paserJson(String json) {
		//"{name:'传智黄盖',email:'huanggai@itcast.cn',url:'image/user.png'}"
		try {
			JSONObject jsonObject=new JSONObject(json);
			String name=jsonObject.getString("name");
			String email=jsonObject.getString("email");
			String url=jsonObject.getString("url");
			UserInfo userInfo=new UserInfo(name, url, email);
			return userInfo;
		} catch (JSONException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public String getKey() {
		return "user";
	}

}


2.Uiutils

	public static View inflate(int id) {
		return View.inflate(getContext(), id, null);
	}


3.MenuHolder

public class MenuHolder extends BaseHolder<UserInfo> implements OnClickListener {
	@ViewInject(R.id.photo_layout)
	private RelativeLayout photo_layout;
	@ViewInject(R.id.image_photo)
	private ImageView image_photo;
	@ViewInject(R.id.user_name)
	private TextView user_name;
	@ViewInject(R.id.user_email)
	private TextView user_email;
	@Override
	public View initView() {
		View view=UiUtils.inflate(R.layout.menu_holder);
		ViewUtils.inject(this, view);
		photo_layout.setOnClickListener(this);
		return view;
	}

	@Override
	public void refreshView(UserInfo data) {
		user_name.setText(data.getName());
		user_email.setText(data.getEmail());
		String url = data.getUrl();//image/user.png
		bitmapUtils.display(image_photo, HttpHelper.URL+"image?name="+url);
		
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.photo_layout:
			//  连接服务器 ...登录
			ThreadManager.getInstance().createLongPool().execute(new Runnable() {
				
				@Override
				public void run() {
					UserProtocol protocol=new UserProtocol();
					final UserInfo load = protocol.load(0);
					UiUtils.runOnUiThread(new Runnable() {
						
						@Override
						public void run() {
							setData(load); // 当调用该方法的时候  就会调用refreshView
						}
					});
				}
			});
			break;
		}
	}

}


 

5.条目的点击事件

1.DefaultAdapter

public DefaultAdapter(List<Data> datas, ListView lv) {
		this.datas = datas;
		// 给ListView设置条目的点击事件
		lv.setOnItemClickListener(this);
		this.lv = lv;
	}

	// ListView 条目点击事件回调的方法
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		// Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();
		position = position - lv.getHeaderViewsCount();// 获取到顶部条目的数量
														// 位置去掉顶部view的数量
		onInnerItemClick(position);
	}
	/**在该方法去处理条目的点击事件*/
	public void onInnerItemClick(int position) {
		//在子类中复写该方法
	}


2.在子类中复写方法(HomeFragment)

listView.setAdapter(new ListBaseAdapter(datas,listView){

			@Override
			protected List<AppInfo> onload() {
				HomeProtocol protocol=new HomeProtocol();
				List<AppInfo> load = protocol.load(datas.size());
				datas.addAll(load);
				return load;
			}
			

			@Override
			public void onInnerItemClick(int position) {
				super.onInnerItemClick(position);
				Toast.makeText(getActivity(), "position:"+position, 0).show();
				/*AppInfo appInfo = datas.get(position);
				Intent intent=new Intent(UiUtils.getContext(), DetailActivity.class);
				intent.putExtra("packageName", appInfo.getPackageName());
				startActivity(intent);*/
			}
			
		});


 

6.切换DetailActivity

1.跳转到DetailActivity

 

 

2.DetailActivity

(1)四种界面,五种状态------复用-LoadPager-----------------------可直接用

/***
 * 创建了自定义帧布局 把baseFragment 一部分代码 抽取到这个类中
 * 
 * @author itcast
 * 
 */
public abstract class LoadingPage extends FrameLayout {

	public static final int STATE_UNKOWN = 0;
	public static final int STATE_LOADING = 1;
	public static final int STATE_ERROR = 2;
	public static final int STATE_EMPTY = 3;
	public static final int STATE_SUCCESS = 4;
	public int state = STATE_UNKOWN;

	private View loadingView;// 加载中的界面
	private View errorView;// 错误界面
	private View emptyView;// 空界面
	private View successView;// 加载成功的界面

	public LoadingPage(Context context) {
		super(context);
		init();
	}

	public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public LoadingPage(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		loadingView = createLoadingView(); // 创建了加载中的界面
		if (loadingView != null) {
			this.addView(loadingView, new FrameLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		}
		errorView = createErrorView(); // 加载错误界面
		if (errorView != null) {
			this.addView(errorView, new FrameLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		}
		emptyView = createEmptyView(); // 加载空的界面
		if (emptyView != null) {
			this.addView(emptyView, new FrameLayout.LayoutParams(
					LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		}
		showPage();// 根据不同的状态显示不同的界面
	}

	// 根据不同的状态显示不同的界面
	private void showPage() {
		if (loadingView != null) {
			loadingView.setVisibility(state == STATE_UNKOWN
					|| state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
		}
		if (errorView != null) {
			errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE
					: View.INVISIBLE);
		}
		if (emptyView != null) {
			emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE
					: View.INVISIBLE);
		}
		if (state == STATE_SUCCESS) {
			if (successView == null) {
				successView = createSuccessView();
				this.addView(successView, new FrameLayout.LayoutParams(
						LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
			}
			successView.setVisibility(View.VISIBLE);
		} else {
			if (successView != null) {
				successView.setVisibility(View.INVISIBLE);
			}
		}
	}

	/* 创建了空的界面 */
	private View createEmptyView() {
		View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_empty,
				null);
		return view;
	}

	/* 创建了错误界面 */
	private View createErrorView() {
		View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_error,
				null);
		Button page_bt = (Button) view.findViewById(R.id.page_bt);
		page_bt.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				show();
			}
		});
		return view;
	}

	/* 创建加载中的界面 */
	private View createLoadingView() {
		View view = View.inflate(UiUtils.getContext(),
				R.layout.loadpage_loading, null);
		return view;
	}

	public enum LoadResult {
		error(2), empty(3), success(4);

		int value;

		LoadResult(int value) {
			this.value = value;
		}

		public int getValue() {
			return value;
		}

	}

	// 根据服务器的数据 切换状态
	public void show() {
		if (state == STATE_ERROR || state == STATE_EMPTY) {
			state = STATE_LOADING;
		}
		// 请求服务器 获取服务器上数据 进行判断
		// 请求服务器 返回一个结果
		ThreadManager.getInstance().createLongPool().execute(new Runnable() {
			
			@Override
			public void run() {
				SystemClock.sleep(500);
				final LoadResult result = load();
				UiUtils.runOnUiThread(new Runnable() {

					@Override
					public void run() {
						if (result != null) {
							state = result.getValue();
							showPage(); // 状态改变了,重新判断当前应该显示哪个界面
						}
					}
				});
			}
		});
		
		
		showPage();

	}

	/***
	 * 创建成功的界面
	 * 
	 * @return
	 */
	public abstract View createSuccessView();

	/**
	 * 请求服务器
	 * 
	 * @return
	 */
	protected abstract LoadResult load();
}


(2)请求服务器

     联网协议DetailProtocol

 

public class DetailProtocol extends BaseProtocol<AppInfo> {
	String packageName;

	public DetailProtocol(String packageName) {
		super();
		this.packageName = packageName;
	}

	@Override
	public AppInfo paserJson(String json) {
		try {
			JSONObject object = new JSONObject(json);
			long id = object.getLong("id");
			String name = object.getString("name");
			String packageName = object.getString("packageName");
			String iconUrl = object.getString("iconUrl");
			float stars = Float.parseFloat(object.getString("stars"));
			long size = object.getLong("size");
			String downloadUrl = object.getString("downloadUrl");
			String des = object.getString("des");
			String downloadNum = object.getString("downloadNum");
			String version = object.getString("version");
			String date = object.getString("date");
			String author = object.getString("author");
			List<String> screen = new ArrayList<String>();
			JSONArray screenArray = object.getJSONArray("screen");
			for (int i = 0; i < screenArray.length(); i++) {
				screen.add(screenArray.getString(i));
			}

			List<String> safeUrl = new ArrayList<String>();
			List<String> safeDesUrl = new ArrayList<String>();
			List<String> safeDes = new ArrayList<String>();
			List<Integer> safeDesColor = new ArrayList<Integer>();
			JSONArray jsonArray = object.getJSONArray("safe");
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				safeUrl.add(jsonObject.getString("safeUrl"));
				safeDesUrl.add(jsonObject.getString("safeDesUrl"));
				safeDes.add(jsonObject.getString("safeDes"));
				safeDesColor.add(jsonObject.getInt("safeDesColor"));

			}
			AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,
					stars, size, downloadUrl, des, downloadNum, version, date,
					author, screen, safeUrl, safeDesUrl, safeDes, safeDesColor);
			return appInfo;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public String getKey() {
		return "detail";
	}

	@Override
	protected String getParams() {
		return "&packageName=" + packageName;
	}
}


   AppInfo

 

public class AppInfo {
	private long id;
	private String name;
	private String packageName;
	private String iconUrl;
	private float stars;
	private long size;
	private String downloadUrl;
	private String des;
	
	//-------------  在DetailActivity 额外用到的数据
	private String downloadNum;
	private String version;
	private String date;
	private String author;
	private List<String> screen;
	
	private List<String> safeUrl;
	private List<String> safeDesUrl;
	private List<String> safeDes;
	private List<Integer> safeDesColor; 
	
	
	
	
	public AppInfo(long id, String name, String packageName, String iconUrl,
			float stars, long size, String downloadUrl, String des,
			String downloadNum, String version, String date, String author,
			List<String> screen, List<String> safeUrl, List<String> safeDesUrl,
			List<String> safeDes, List<Integer> safeDesColor) {
		super();
		this.id = id;
		this.name = name;
		this.packageName = packageName;
		this.iconUrl = iconUrl;
		this.stars = stars;
		this.size = size;
		this.downloadUrl = downloadUrl;
		this.des = des;
		this.downloadNum = downloadNum;
		this.version = version;
		this.date = date;
		this.author = author;
		this.screen = screen;
		this.safeUrl = safeUrl;
		this.safeDesUrl = safeDesUrl;
		this.safeDes = safeDes;
		this.safeDesColor = safeDesColor;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPackageName() {
		return packageName;
	}
	public void setPackageName(String packageName) {
		this.packageName = packageName;
	}
	public String getIconUrl() {
		return iconUrl;
	}
	public void setIconUrl(String iconUrl) {
		this.iconUrl = iconUrl;
	}
	public float getStars() {
		return stars;
	}
	public void setStars(float stars) {
		this.stars = stars;
	}
	public long getSize() {
		return size;
	}
	public void setSize(long size) {
		this.size = size;
	}
	public String getDownloadUrl() {
		return downloadUrl;
	}
	public void setDownloadUrl(String downloadUrl) {
		this.downloadUrl = downloadUrl;
	}
	public String getDes() {
		return des;
	}
	public void setDes(String des) {
		this.des = des;
	}
	public AppInfo() {
		super();
	}
	public String getDownloadNum() {
		return downloadNum;
	}
	public void setDownloadNum(String downloadNum) {
		this.downloadNum = downloadNum;
	}
	public String getVersion() {
		return version;
	}
	public void setVersion(String version) {
		this.version = version;
	}
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public List<String> getScreen() {
		return screen;
	}
	public void setScreen(List<String> screen) {
		this.screen = screen;
	}
	public List<String> getSafeUrl() {
		return safeUrl;
	}
	public void setSafeUrl(List<String> safeUrl) {
		this.safeUrl = safeUrl;
	}
	public List<String> getSafeDesUrl() {
		return safeDesUrl;
	}
	public void setSafeDesUrl(List<String> safeDesUrl) {
		this.safeDesUrl = safeDesUrl;
	}
	public List<String> getSafeDes() {
		return safeDes;
	}
	public void setSafeDes(List<String> safeDes) {
		this.safeDes = safeDes;
	}
	public List<Integer> getSafeDesColor() {
		return safeDesColor;
	}
	public void setSafeDesColor(List<Integer> safeDesColor) {
		this.safeDesColor = safeDesColor;
	}
	public AppInfo(long id, String name, String packageName, String iconUrl,
			float stars, long size, String downloadUrl, String des) {
		super();
		this.id = id;
		this.name = name;
		this.packageName = packageName;
		this.iconUrl = iconUrl;
		this.stars = stars;
		this.size = size;
		this.downloadUrl = downloadUrl;
		this.des = des;
	}
	@Override
	public String toString() {
		return "AppInfo [id=" + id + ", name=" + name + ", packageName="
				+ packageName + ", iconUrl=" + iconUrl + ", stars=" + stars
				+ ", size=" + size + ", downloadUrl=" + downloadUrl + ", des="
				+ des + "]";
	}
	
	
}
 


 

(3)Intent数据传输

     传递

                                    AppInfo appInfo = datas.get(position);
				Intent intent=new Intent(Uiutils.getContext(), DetailActivity.class);
				intent.putExtra("packageName", appInfo.getPackageName());
				startActivity(intent);

      接收

           @Override
	protected void onCreate(Bundle savedInstanceState) {
		Intent intent = getIntent();  // 获取到打开当前activity的意图对象
		packageName = intent.getStringExtra("packageName");
		super.onCreate(savedInstanceState);
		
		
	}



 

(4)DetalActivity

public class DetailActivity extends BaseActivity {
	private String packageName;
	private AppInfo data;
	@Override
	protected void initView() {
		LoadingPage  loadingPage=new LoadingPage(this) {
			@Override
			protected LoadResult load() {
				return DetailActivity.this.load();
			}
			@Override
			public View createSuccessView() {
				return DetailActivity.this.createSuccessView();
			}
		};
		loadingPage.show();  //  必须调用show方法 才会请求服务器 加载新的界面
		setContentView(loadingPage);
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Intent intent = getIntent();  // 获取到打开当前activity的意图对象
		packageName = intent.getStringExtra("packageName");
		super.onCreate(savedInstanceState);
		
		
	}
	@Override
	protected void initActionBar() {
		super.initActionBar();
		ActionBar actionBar = getSupportActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);
	}
	/**
	 * 加载成功的界面
	 * @return
	 */
	protected View createSuccessView() {
		return null;
		
	}
	/**
	 * 请求服务器加载数据
	 * @return
	 */
	protected LoadResult load() {
		DetailProtocol protocol=new DetailProtocol(packageName);
		data = protocol.load(0);
		if(data==null){
			return LoadResult.error;
		}else{
			return LoadResult.success;
		}
	}
}


7.Detail界面的数据的解析

 1.解析Json,不用框架

                       try {
			JSONObject object = new JSONObject(json);
			long id = object.getLong("id");
			String name = object.getString("name");
			String packageName = object.getString("packageName");
			String iconUrl = object.getString("iconUrl");
			float stars = Float.parseFloat(object.getString("stars"));
			long size = object.getLong("size");
			String downloadUrl = object.getString("downloadUrl");
			String des = object.getString("des");
			String downloadNum = object.getString("downloadNum");
			String version = object.getString("version");
			String date = object.getString("date");
			String author = object.getString("author");
			List<String> screen = new ArrayList<String>();
			JSONArray screenArray = object.getJSONArray("screen");
			for (int i = 0; i < screenArray.length(); i++) {
				screen.add(screenArray.getString(i));
			}

			List<String> safeUrl = new ArrayList<String>();
			List<String> safeDesUrl = new ArrayList<String>();
			List<String> safeDes = new ArrayList<String>();
			List<Integer> safeDesColor = new ArrayList<Integer>();
			JSONArray jsonArray = object.getJSONArray("safe");
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				safeUrl.add(jsonObject.getString("safeUrl"));
				safeDesUrl.add(jsonObject.getString("safeDesUrl"));
				safeDes.add(jsonObject.getString("safeDes"));
				safeDesColor.add(jsonObject.getInt("safeDesColor"));

			}
			AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,
					stars, size, downloadUrl, des, downloadNum, version, date,
					author, screen, safeUrl, safeDesUrl, safeDes, safeDesColor);
			   return appInfo;
		     } catch (Exception e) {
			   e.printStackTrace();
			   return null;
		    }


 

8.通过Holder显示界面

1.应用详情布局

   先搭好架子,用FrameLayout代替,再逐一填充

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/bottom_layout"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/detail_bottom_bg" >
    </FrameLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bottom_layout"
        android:layout_marginBottom="5dp"
        android:fillViewport="true" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <FrameLayout
                android:id="@+id/detail_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:background="@drawable/list_item_bg_normal" />

            <FrameLayout
                android:id="@+id/detail_safe"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/detail_info"
                android:background="@drawable/list_item_bg_normal" />

            <HorizontalScrollView
                android:id="@+id/detail_screen"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/detail_safe"
                android:background="@color/detail_screen_bg"
                android:fillViewport="true"
                android:padding="5dp"
                android:scrollbars="none" />

            <FrameLayout
                android:id="@+id/detail_des"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/detail_screen"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:background="@drawable/list_item_bg_normal" />
        </RelativeLayout>
    </ScrollView>

</RelativeLayout>


2.分成各个Holder实现

3.DetalActivity,逐一添加Holder

   LoadingPage 四种界面五种状态,可直接用

 

public class DetailActivity extends BaseActivity {
	private String packageName;
	private AppInfo data;

	@Override
	protected void initView() {
		LoadingPage loadingPage = new LoadingPage(this) {
			@Override
			protected LoadResult load() {
				return DetailActivity.this.load();
			}

			@Override
			public View createSuccessView() {
				return DetailActivity.this.createSuccessView();
			}
		};
		loadingPage.show(); // 必须调用show方法 才会请求服务器 加载新的界面
		setContentView(loadingPage);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Intent intent = getIntent(); // 获取到打开当前activity的意图对象
		packageName = intent.getStringExtra("packageName");
		super.onCreate(savedInstanceState);

	}

	@Override
	protected void initActionBar() {
		super.initActionBar();
		ActionBar actionBar = getSupportActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);
	}

	/**
	 * 加载成功的界面
	 * 
	 * @return
	 */
	private FrameLayout bottom_layout, detail_info, detail_safe, detail_des;
	private HorizontalScrollView detail_screen;
	private DetailInfoHolder detailInfoHolder;

	protected View createSuccessView() {
		View view = Uiutils.inflate(R.layout.activity_detail);

		// 操作 应用程序信息
		detail_info = (FrameLayout) view.findViewById(R.id.detail_info);
		detailInfoHolder = new DetailInfoHolder();
		detailInfoHolder.setData(data);
		detail_info.addView(detailInfoHolder.getContentView());

		return view;

	}

	/**
	 * 请求服务器加载数据
	 * 
	 * @return
	 */
	protected LoadResult load() {
		DetailProtocol protocol = new DetailProtocol(packageName);
		data = protocol.load(0);
		if (data == null) {
			return LoadResult.error;
		} else {
			return LoadResult.success;
		}
	}
}


 

 

9.应用详情&应用图片

1.每一部分都为一个Holder

2.

(1)布局

<p><RelativeLayout xmlns:android="<a target=_blank href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"
    android:id="@+id/item_info_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp" ></p><p>    <RelativeLayout
        android:id="@+id/item_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" ></p><p>        <ImageView
            android:id="@+id/item_icon"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_centerVertical="true"
            android:layout_marginRight="8dp"
            android:scaleType="fitXY"
            android:src="@drawable/ic_default" /></p><p>        <RelativeLayout
            android:id="@+id/item_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/item_icon" ></p><p>            <TextView
                android:id="@+id/item_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff333333"
                android:textSize="16dp" /></p><p>            <RatingBar
                android:id="@+id/item_rating"
                android:layout_width="wrap_content"
                android:layout_height="@dimen/list_item_rating_height"
                android:layout_below="@id/item_title"
                android:layout_marginTop="@dimen/app_detail_rating_margin"
                android:isIndicator="true"
                android:progressDrawable="@drawable/process_ratingbar"
                android:rating="2.5" />
        </RelativeLayout>
    </RelativeLayout></p><p>    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/item_top"
        android:orientation="vertical" ></p><p>        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:orientation="horizontal" ></p><p>            <TextView
                android:id="@+id/item_download"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" /></p><p>            <TextView
                android:id="@+id/item_version"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout></p><p>        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:orientation="horizontal" ></p><p>            <TextView
                android:id="@+id/item_date"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" /></p><p>            <TextView
                android:id="@+id/item_size"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout>
    </LinearLayout></p><p></RelativeLayout></p>


(2)    DetailInfoHolder

public class DetailInfoHolder extends BaseHolder<AppInfo>{
	@ViewInject(R.id.item_icon)
	private ImageView item_icon;
	@ViewInject(R.id.item_title)
	private TextView item_title;
	@ViewInject(R.id.item_rating)
	private RatingBar item_rating;
	@ViewInject(R.id.item_download)
	private TextView item_download;
	@ViewInject(R.id.item_version)
	private TextView item_version;
	@ViewInject(R.id.item_date)
	private TextView item_date;
	@ViewInject(R.id.item_size)
	private TextView item_size;
	@Override
	public View initView() {
		View view=Uiutils.inflate(R.layout.detals_app_info);
		ViewUtils.inject(this, view);
		return view;
	}

	@Override
	public void refreshView(AppInfo data) {
		bitmapUtils.display(item_icon, HttpHelper.URL+"image?name="+data.getIconUrl());
		item_title.setText(data.getName());
		item_rating.setRating(data.getStars());
		item_download.setText("下载:"+data.getDownloadNum());
		item_version.setText("版本:"+data.getVersion());
		item_date.setText("时间:"+data.getDate());
		item_size.setText("大小:"+Formatter.formatFileSize(Uiutils.getContext(), data.getSize()));		
	}

}


(3)添加

//  操作 应用程序信息
		detail_info=(FrameLayout) view.findViewById(R.id.detail_info);
		detailInfoHolder=new DetailInfoHolder();
		detailInfoHolder.setData(data);
		detail_info.addView(detailInfoHolder.getContentView());


3.应用图片

 

(1)布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <ImageView
        android:id="@+id/screen_1"
        android:layout_width="90dp"
        android:layout_height="150dp"
        android:paddingRight="5dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_default" />

    <ImageView
        android:id="@+id/screen_2"
        android:layout_width="90dp"
        android:layout_height="150dp"
        android:layout_toRightOf="@id/screen_1"
        android:paddingRight="5dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_default" />

    <ImageView
        android:id="@+id/screen_3"
        android:layout_width="90dp"
        android:layout_height="150dp"
        android:layout_toRightOf="@id/screen_2"
        android:paddingRight="5dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_default" />

    <ImageView
        android:id="@+id/screen_4"
        android:layout_width="90dp"
        android:layout_height="150dp"
        android:layout_toRightOf="@id/screen_3"
        android:paddingRight="5dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_default" />

    <ImageView
        android:id="@+id/screen_5"
        android:layout_width="90dp"
        android:layout_height="150dp"
        android:layout_toRightOf="@id/screen_4"
        android:paddingRight="5dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_default" />

</RelativeLayout>


 

(2)DetailScreenHolder

 

public class DetailScreenHolder extends BaseHolder<AppInfo> {
	private ImageView[] ivs;
	@Override
	public View initView() {
		View view=UiUtils.inflate(R.layout.detail_screen);
		ivs=new ImageView[5];
		ivs[0]=(ImageView) view.findViewById(R.id.screen_1);
		ivs[1]=(ImageView) view.findViewById(R.id.screen_2);
		ivs[2]=(ImageView) view.findViewById(R.id.screen_3);
		ivs[3]=(ImageView) view.findViewById(R.id.screen_4);
		ivs[4]=(ImageView) view.findViewById(R.id.screen_5);
		return view;
	}

	@Override
	public void refreshView(AppInfo data) {
		List<String> screen = data.getScreen(); // 集合的大小有可能小于5 
		for(int i=0;i<5;i++){
			if(i<screen.size()){
				ivs[i].setVisibility(View.VISIBLE);
				bitmapUtils.display(ivs[i], HttpHelper.URL+"image?name="+screen.get(i));
			}else{
				ivs[i].setVisibility(View.GONE);
			}
			
		}
	}

}

 

(3)添加

	// 中间5张图片
		detail_screen=(HorizontalScrollView) view.findViewById(R.id.detail_screen);
		screenHolder=new DetailScreenHolder();
		screenHolder.setData(data);
		detail_screen.addView(screenHolder.getContentView());


 

 

4.附加

   完整BaseProtocol

public abstract class BaseProtocol<T> {
	public T load(int index) {
		SystemClock.sleep(1000);
		// 加载本地数据
		String json = loadLocal(index);
		if (json == null) {
			// 请求服务器
			json = loadServer(index);
			if (json != null) {
				saveLocal(json, index);
			}
		}
		if (json != null) {
			return paserJson(json);
		} else {
			return null;
		}
	}

	private String loadServer(int index) {
		HttpResult httpResult = HttpHelper.get(HttpHelper.URL + getKey()
				+ "?index=" + index+getParams());
		if (httpResult != null) {
			String json = httpResult.getString();
			return json;
		} else {
			return null;
		}
	}
	/**
	 * 额外带的参数
	 * @return
	 */
	protected String getParams() {
		return "";
	}

	private void saveLocal(String json, int index) {

		BufferedWriter bw = null;
		try {
			File dir = FileUtils.getCacheDir();
			// 在第一行写一个过期时间
			File file = new File(dir, getKey() + "_" + index+getParams()); // /mnt/sdcard/googlePlay/cache/home_0
			FileWriter fw = new FileWriter(file);
			bw = new BufferedWriter(fw);
			bw.write(System.currentTimeMillis() + 1000 * 100 + "");
			bw.newLine();// 换行
			bw.write(json);// 把整个json文件保存起来
			bw.flush();
			bw.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(bw);
		}
	}

	private String loadLocal(int index) {
		// 如果发现文件已经过期了 就不要再去复用缓存了
		File dir = FileUtils.getCacheDir();// 获取缓存所在的文件夹
		File file = new File(dir, getKey() + "_" + index+getParams());
		try {
			FileReader fr = new FileReader(file);
			BufferedReader br = new BufferedReader(fr);
			long outOfDate = Long.parseLong(br.readLine());
			if (System.currentTimeMillis() > outOfDate) {
				return null;
			} else {
				String str = null;
				StringWriter sw = new StringWriter();
				while ((str = br.readLine()) != null) {

					sw.write(str);
				}
				return sw.toString();
			}

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 解析json
	 * 
	 * @param json
	 * @return
	 */
	public abstract T paserJson(String json);

	/**
	 * 说明了关键字
	 * 
	 * @return
	 */
	public abstract String getKey(); 
}


 getParams是为了标记每一个应用的包名的本地缓存

 

 

10.应用详情安全界面

没有点击展开状态

1.布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/safe_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp" >

    <RelativeLayout
        android:id="@+id/safe_title_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical" >

        <LinearLayout
            android:id="@+id/safe_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/iv_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="centerInside" />

            <ImageView
                android:id="@+id/iv_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:scaleType="centerInside" />

            <ImageView
                android:id="@+id/iv_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:scaleType="centerInside" />

            <ImageView
                android:id="@+id/iv_4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:scaleType="centerInside" />
        </LinearLayout>

        <ImageView
            android:id="@+id/safe_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:scaleType="centerInside"
            android:src="@drawable/arrow_down" />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/safe_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/safe_title_layout"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/des_layout_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/des_iv_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="centerInside" />

            <TextView
                android:id="@+id/des_tv_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/des_layout_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/des_iv_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="centerInside" />

            <TextView
                android:id="@+id/des_tv_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/des_layout_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/des_iv_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="centerInside" />

            <TextView
                android:id="@+id/des_tv_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/des_layout_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="3dp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/des_iv_4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:scaleType="centerInside" />

            <TextView
                android:id="@+id/des_tv_4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#ff7a7a7a"
                android:textSize="12dp" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>


2.DetailSafeHolder

public class DetailSafeHolder extends BaseHolder<AppInfo> {
	@ViewInject(R.id.safe_layout)
	private RelativeLayout safe_layout;
	@ViewInject(R.id.safe_content)
	private LinearLayout safe_content;
	@ViewInject(R.id.safe_arrow)
	private ImageView safe_arrow;
	ImageView[] ivs;
	ImageView[] iv_des;
	TextView[] tv_des;
	LinearLayout[] des_layout;

	@Override
	public View initView() {
		View view = Uiutils.inflate(R.layout.detail_safe);
		ViewUtils.inject(this, view);

		ivs = new ImageView[4]; // 初始化标题栏的图片
		ivs[0] = (ImageView) view.findViewById(R.id.iv_1);
		ivs[1] = (ImageView) view.findViewById(R.id.iv_2);
		ivs[2] = (ImageView) view.findViewById(R.id.iv_3);
		ivs[3] = (ImageView) view.findViewById(R.id.iv_4);
		iv_des = new ImageView[4]; // 初始化每个条目描述的图片
		iv_des[0] = (ImageView) view.findViewById(R.id.des_iv_1);
		iv_des[1] = (ImageView) view.findViewById(R.id.des_iv_2);
		iv_des[2] = (ImageView) view.findViewById(R.id.des_iv_3);
		iv_des[3] = (ImageView) view.findViewById(R.id.des_iv_4);
		tv_des = new TextView[4]; // 初始化每个条目描述的文本
		tv_des[0] = (TextView) view.findViewById(R.id.des_tv_1);
		tv_des[1] = (TextView) view.findViewById(R.id.des_tv_2);
		tv_des[2] = (TextView) view.findViewById(R.id.des_tv_3);
		tv_des[3] = (TextView) view.findViewById(R.id.des_tv_4);

		des_layout = new LinearLayout[4]; // 初始化条目线性布局
		des_layout[0] = (LinearLayout) view.findViewById(R.id.des_layout_1);
		des_layout[1] = (LinearLayout) view.findViewById(R.id.des_layout_2);
		des_layout[2] = (LinearLayout) view.findViewById(R.id.des_layout_3);
		des_layout[3] = (LinearLayout) view.findViewById(R.id.des_layout_4);

		/*LayoutParams layoutParams = safe_content.getLayoutParams();
		layoutParams.height = 0;
		safe_content.setLayoutParams(layoutParams);
		safe_arrow.setImageResource(R.drawable.arrow_down);*/
		return view;
	}

	@Override
	public void refreshView(AppInfo data) {

		List<String> safeUrl = data.getSafeUrl();
		List<String> safeDesUrl = data.getSafeDesUrl();
		List<String> safeDes = data.getSafeDes();
		List<Integer> safeDesColor = data.getSafeDesColor(); // 0 1 2 3
		for (int i = 0; i < 4; i++) {
			if (i < safeUrl.size() && i < safeDesUrl.size()
					&& i < safeDes.size() && i < safeDesColor.size()) {
				ivs[i].setVisibility(View.VISIBLE);
				des_layout[i].setVisibility(View.VISIBLE);
				bitmapUtils.display(ivs[i], HttpHelper.URL + "image?name="
						+ safeUrl.get(i));
				bitmapUtils.display(iv_des[i], HttpHelper.URL + "image?name="
						+ safeDesUrl.get(i));
				tv_des[i].setText(safeDes.get(i));
				// 根据服务器数据显示不同的颜色
				int color;
				int colorType = safeDesColor.get(i);
				if (colorType >= 1 && colorType <= 3) {
					color = Color.rgb(255, 153, 0); // 00 00 00
				} else if (colorType == 4) {
					color = Color.rgb(0, 177, 62);
				} else {
					color = Color.rgb(122, 122, 122);
				}
				tv_des[i].setTextColor(color);

			} else {
				ivs[i].setVisibility(View.GONE);
				des_layout[i].setVisibility(View.GONE);
			}

		}

	}

}


3.添加

	// 安全标记
		detail_safe = (FrameLayout) view.findViewById(R.id.detail_safe);
		safeHolder = new DetailSafeHolder();
		safeHolder.setData(data);
		detail_safe.addView(safeHolder.getContentView());


 

11.值动画

1.点击收起展开

(1)方法一:使下面部分点击隐藏visiable------效果差

2.值动画Demo------数值慢慢变化

   只可以在3.0以后使用,所以要使用Jar包

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ValueAnimator animator=ValueAnimator.ofInt(0,50,150);//  0-50 -150 
		animator.addUpdateListener(new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				int value=(Integer) animation.getAnimatedValue();  // 当前时间点变化后的值
				System.out.println(value);
			}
		});
		animator.setDuration(500);
		animator.start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

}


3.应用---让LinearLayout的高度慢慢变化

   (1)使用jar包

   (2)获取控件的高度

a.获取控件实际高度

	//onMeasure()  制定测量的规则 
	// measure() 实际测量 
	/**
	 * 获取控件实际的高度
	 */
	public int getMeasureHeight(){
		int width = safe_content.getMeasuredWidth();  //  由于宽度不会发生变化  宽度的值取出来
		safe_content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;//  让高度包裹内容

		//    参数1  测量控件mode    参数2  大小 
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);  //  mode+size
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);// 我的高度 最大是1000
		// 测量规则 宽度是一个精确的值width, 高度最大是1000,以实际为准
		safe_content.measure(widthMeasureSpec, heightMeasureSpec); // 通过该方法重新测量控件 
		
		return safe_content.getMeasuredHeight();
		
		
		
	}


b.值动画

// 值动画
			ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);
			final RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) safe_content.getLayoutParams();
			animator.addUpdateListener(new AnimatorUpdateListener() {  // 监听值的变化
				
				@Override
				public void onAnimationUpdate(ValueAnimator animator) {
					int value=(Integer) animator.getAnimatedValue();// 运行当前时间点的一个值
					layoutParams.height=value;
					safe_content.setLayoutParams(layoutParams);// 刷新界面
					System.out.println(value);
				}
			});


c.监听动画完成,改变状态

animator.addListener(new AnimatorListener() {  // 监听动画执行
				//当动画开始执行的时候调用
				@Override
				public void onAnimationStart(Animator arg0) {
					// TODO Auto-generated method stub
					
				}
				@Override
				public void onAnimationRepeat(Animator arg0) {
					
				}
				@Override
				public void onAnimationEnd(Animator arg0) {
					if(flag){
						safe_arrow.setImageResource(R.drawable.arrow_up);
					}else{
						safe_arrow.setImageResource(R.drawable.arrow_down);
					}
				}
				@Override
				public void onAnimationCancel(Animator arg0) {
					
				}
			});


4.完整

public class DetailSafeHolder extends BaseHolder<AppInfo> implements
		OnClickListener {
	@ViewInject(R.id.safe_layout)
	private RelativeLayout safe_layout;
	@ViewInject(R.id.safe_content)
	private LinearLayout safe_content;
	@ViewInject(R.id.safe_arrow)
	private ImageView safe_arrow;
	ImageView[] ivs;
	ImageView[] iv_des;
	TextView[] tv_des;
	LinearLayout[] des_layout;

	@Override
	public View initView() {
		View view = UiUtils.inflate(R.layout.detail_safe);
		ViewUtils.inject(this, view);

		ivs = new ImageView[4]; // 初始化标题栏的图片
		ivs[0] = (ImageView) view.findViewById(R.id.iv_1);
		ivs[1] = (ImageView) view.findViewById(R.id.iv_2);
		ivs[2] = (ImageView) view.findViewById(R.id.iv_3);
		ivs[3] = (ImageView) view.findViewById(R.id.iv_4);
		iv_des = new ImageView[4]; // 初始化每个条目描述的图片
		iv_des[0] = (ImageView) view.findViewById(R.id.des_iv_1);
		iv_des[1] = (ImageView) view.findViewById(R.id.des_iv_2);
		iv_des[2] = (ImageView) view.findViewById(R.id.des_iv_3);
		iv_des[3] = (ImageView) view.findViewById(R.id.des_iv_4);
		tv_des = new TextView[4]; // 初始化每个条目描述的文本
		tv_des[0] = (TextView) view.findViewById(R.id.des_tv_1);
		tv_des[1] = (TextView) view.findViewById(R.id.des_tv_2);
		tv_des[2] = (TextView) view.findViewById(R.id.des_tv_3);
		tv_des[3] = (TextView) view.findViewById(R.id.des_tv_4);

		des_layout = new LinearLayout[4]; // 初始化条目线性布局
		des_layout[0] = (LinearLayout) view.findViewById(R.id.des_layout_1);
		des_layout[1] = (LinearLayout) view.findViewById(R.id.des_layout_2);
		des_layout[2] = (LinearLayout) view.findViewById(R.id.des_layout_3);
		des_layout[3] = (LinearLayout) view.findViewById(R.id.des_layout_4);

		
		//safe_content初始高度设为0,即收起状态
		LayoutParams layoutParams = safe_content.getLayoutParams();
		layoutParams.height=0;
		safe_content.setLayoutParams(layoutParams);
		safe_arrow.setImageResource(R.drawable.arrow_down);
		return view;
	}

	@Override
	public void refreshView(AppInfo data) {
		safe_layout.setOnClickListener(this);

		List<String> safeUrl = data.getSafeUrl();
		List<String> safeDesUrl = data.getSafeDesUrl();
		List<String> safeDes = data.getSafeDes();
		List<Integer> safeDesColor = data.getSafeDesColor(); // 0 1 2 3
		for (int i = 0; i < 4; i++) {
			if (i < safeUrl.size() && i < safeDesUrl.size()
					&& i < safeDes.size() && i < safeDesColor.size()) {
				ivs[i].setVisibility(View.VISIBLE);
				des_layout[i].setVisibility(View.VISIBLE);
				bitmapUtils.display(ivs[i], HttpHelper.URL + "image?name="
						+ safeUrl.get(i));
				bitmapUtils.display(iv_des[i], HttpHelper.URL + "image?name="
						+ safeDesUrl.get(i));
				tv_des[i].setText(safeDes.get(i));
				// 根据服务器数据显示不同的颜色
				int color;
				int colorType = safeDesColor.get(i);
				if (colorType >= 1 && colorType <= 3) {
					color = Color.rgb(255, 153, 0); // 00 00 00
				} else if (colorType == 4) {
					color = Color.rgb(0, 177, 62);
				} else {
					color = Color.rgb(122, 122, 122);
				}
				tv_des[i].setTextColor(color);

			} else {
				ivs[i].setVisibility(View.GONE);
				des_layout[i].setVisibility(View.GONE);
			}

		}

	}

	boolean flag=false;

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.safe_layout) {
			int  startHeight;
			int targetHeight;
			if (!flag) {    //  展开的动画  
				startHeight=0;
				targetHeight=getMeasureHeight();
				
				flag = true;
				//safe_content.setVisibility(View.VISIBLE);
				safe_content.getMeasuredHeight();  //  0  
			} else {
				flag=false;
				//safe_content.setVisibility(View.GONE);
				startHeight=getMeasureHeight();
				targetHeight=0;
			}
			// 值动画
			ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);
			final RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) safe_content.getLayoutParams();
			animator.addUpdateListener(new AnimatorUpdateListener() {  // 监听值的变化
				
				@Override
				public void onAnimationUpdate(ValueAnimator animator) {
					int value=(Integer) animator.getAnimatedValue();// 运行当前时间点的一个值
					layoutParams.height=value;
					safe_content.setLayoutParams(layoutParams);// 刷新界面
					System.out.println(value);
				}
			});
			
			animator.addListener(new AnimatorListener() {  // 监听动画执行
				//当动画开始执行的时候调用
				@Override
				public void onAnimationStart(Animator arg0) {
					// TODO Auto-generated method stub
					
				}
				@Override
				public void onAnimationRepeat(Animator arg0) {
					
				}
				@Override
				public void onAnimationEnd(Animator arg0) {
					if(flag){
						safe_arrow.setImageResource(R.drawable.arrow_up);
					}else{
						safe_arrow.setImageResource(R.drawable.arrow_down);
					}
				}
				@Override
				public void onAnimationCancel(Animator arg0) {
					
				}
			});
			
			animator.setDuration(500);
			animator.start();
			
			
		}
	}
	
	//onMeasure()  制定测量的规则 
	// measure() 实际测量 
	/**
	 * 获取控件实际的高度
	 */
	public int getMeasureHeight(){
		int width = safe_content.getMeasuredWidth();  //  由于宽度不会发生变化  宽度的值取出来
		safe_content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;//  让高度包裹内容

		//    参数1  测量控件mode    参数2  大小 
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);  //  mode+size
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);// 我的高度 最大是1000
		// 测量规则 宽度是一个精确的值width, 高度最大是1000,以实际为准
		safe_content.measure(widthMeasureSpec, heightMeasureSpec); // 通过该方法重新测量控件 
		
		return safe_content.getMeasuredHeight();
		
		
		
	}

}


 12.描述界面值动画

1.布局----展开的

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/des_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp" >

    <TextView
        android:id="@+id/des_titile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="end"
        android:singleLine="true"
        android:text="@string/app_detail_introduction"
        android:textColor="#3c3c3c"
        android:textSize="14dp" />

    <TextView
        android:id="@+id/des_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/des_titile"
        android:layout_marginTop="5dp"
        android:textColor="#7a7a7a"
        android:textSize="14dp" 
        />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/des_content"
        android:layout_marginTop="5dp"
        android:gravity="center_vertical" >

        <TextView
            android:id="@+id/des_author"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:singleLine="true"
            android:textColor="#b3b3b3"
            android:textSize="14dp" />

        <ImageView
            android:id="@+id/des_arrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:scaleType="centerInside"
            android:src="@drawable/arrow_down" />
    </RelativeLayout>

</RelativeLayout>


2.获取TextView自己的高度(即原来展开的高度)

/**
	 * 获取TextView 自己本身的高度
	 * @return
	 */
	public int getLongMeasureHeight(){
		int width=des_content.getMeasuredWidth(); // 开始宽度
		des_content.getLayoutParams().height= ViewGroup.LayoutParams.WRAP_CONTENT;// 高度包裹内容
		
		
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);
		des_content.measure(widthMeasureSpec,heightMeasureSpec);//
		return des_content.getMeasuredHeight();
	}


3.获取TextView七行的高度

/**
	 * 获取7行的高度
	 * @return
	 */
	public int getShortMeasureHeight(){
		// 复制一个新的TextView 用来测量,最好不要在之前的TextView测量 有可能影响其它代码执行
		TextView textView=new TextView(UiUtils.getContext());
		textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);//设置字体大小14dp
		textView.setMaxLines(7);
		textView.setLines(7);// 强制有7行
		int width=des_content.getMeasuredWidth(); // 开始宽度
		
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);
		textView.measure(widthMeasureSpec, heightMeasureSpec);
		return textView.getMeasuredHeight();
	}


4.默认一开始只有7行高度

                  //des_content 起始高度7行的高度
		LayoutParams layoutParams = des_content.getLayoutParams();
		layoutParams.height=getShortMeasureHeight();
		des_content.setLayoutParams(layoutParams);


 

5.点击事件执行动画

    private void expand() {
 		int startHeight;
		int targetHeight;
		if(!flag){
			flag=true;
			startHeight=getShortMeasureHeight();
			targetHeight=getLongMeasureHeight();
		}else{
			flag=false;
			startHeight=getLongMeasureHeight();
			targetHeight=getShortMeasureHeight();
		}
		final LayoutParams layoutParams = des_content.getLayoutParams();
		ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);
		animator.addUpdateListener(new AnimatorUpdateListener() {//监听动画数值变化
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				int value=(Integer) animation.getAnimatedValue();
				layoutParams.height=value;
				des_content.setLayoutParams(layoutParams);
 			}
		});
 
		animator.setDuration(500);//设置动画持续时间
		animator.start();
	}


 

5.改变箭头方向

   监听动画完成

animator.addListener(new AnimatorListener() {  // 监听动画执行
			//当动画开始执行的时候调用
			@Override
			public void onAnimationStart(Animator arg0) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void onAnimationRepeat(Animator arg0) {
				
			}
			@Override
			public void onAnimationEnd(Animator arg0) {
				if(flag){
					des_arrow.setImageResource(R.drawable.arrow_up);
				}else{
					des_arrow.setImageResource(R.drawable.arrow_down);
				}
			}
			@Override
			public void onAnimationCancel(Animator arg0) {
				
			}
		});


 

6.让ScrollView自动滑到底

(1)递归获取ScrollView

public ScrollView getScrollView(View view){
		ViewParent parent = view.getParent();
		if(parent instanceof ViewGroup){
			ViewGroup group=(ViewGroup) parent;
			if(group instanceof ScrollView){
				return (ScrollView)group;
			}else{
				return getScrollView(group);
			}
			
		}else{
			return null;
		}
		
	}


(2)让ScrollView移动到最下面

scrollView.scrollTo(0, scrollView.getMeasuredHeight());// 让scrollView 移动到最下面
			}


7.DetailDesHolder

public class DetailDesHolder extends BaseHolder<AppInfo> implements OnClickListener {
	@ViewInject(R.id.des_content)
	private TextView des_content;
	@ViewInject(R.id.des_author)
	private TextView des_author;
	@ViewInject(R.id.des_arrow)
	private ImageView des_arrow;
	@ViewInject(R.id.des_layout)
	private RelativeLayout des_layout;
	
	@Override
	public View initView() {
		View view=UiUtils.inflate(R.layout.detail_des);
		ViewUtils.inject(this, view);
		return view;
	}

	@Override
	public void refreshView(AppInfo data) {
		des_content.setText(data.getDes());
		des_author.setText("作者:"+data.getAuthor());
		des_layout.setOnClickListener(this);
		
		//des_content 起始高度7行的高度
		LayoutParams layoutParams = des_content.getLayoutParams();
		layoutParams.height=getShortMeasureHeight();
		des_content.setLayoutParams(layoutParams);
		des_arrow.setImageResource(R.drawable.arrow_down);
	}
	/**
	 * 获取7行的高度
	 * @return
	 */
	public int getShortMeasureHeight(){
		// 复制一个新的TextView 用来测量,最好不要在之前的TextView测量 有可能影响其它代码执行
		TextView textView=new TextView(UiUtils.getContext());
		textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);//设置字体大小14dp
		textView.setMaxLines(7);
		textView.setLines(7);// 强制有7行
		int width=des_content.getMeasuredWidth(); // 开始宽度
		
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);
		textView.measure(widthMeasureSpec, heightMeasureSpec);
		return textView.getMeasuredHeight();
	}
	/**
	 * 获取TextView 自己本身的高度
	 * @return
	 */
	public int getLongMeasureHeight(){
		int width=des_content.getMeasuredWidth(); // 开始宽度
		des_content.getLayoutParams().height= ViewGroup.LayoutParams.WRAP_CONTENT;// 高度包裹内容
		
		
		int widthMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY, width);
		int heightMeasureSpec=MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);
		des_content.measure(widthMeasureSpec,heightMeasureSpec);//
		return des_content.getMeasuredHeight();
	}
	boolean flag;// true展开了 false 没有展开
	@Override
	public void onClick(View v) {
		expand();
	}
	ScrollView scrollView;
//	scrollView.scrollTo(0, scrollView.getMeasuredHeight())
	/**
	 * 获取到界面的ScollView
	 */
	public ScrollView getScrollView(View view){
		ViewParent parent = view.getParent();
		if(parent instanceof ViewGroup){
			ViewGroup group=(ViewGroup) parent;
			if(group instanceof ScrollView){
				return (ScrollView)group;
			}else{
				return getScrollView(group);
			}
			
		}else{
			return null;
		}
		
	}
	
	private void expand() {
		scrollView=getScrollView(des_layout);
		int startHeight;
		int targetHeight;
		if(!flag){
			flag=true;
			startHeight=getShortMeasureHeight();
			targetHeight=getLongMeasureHeight();
		}else{
			flag=false;
			startHeight=getLongMeasureHeight();
			targetHeight=getShortMeasureHeight();
		}
		final LayoutParams layoutParams = des_content.getLayoutParams();
		ValueAnimator animator=ValueAnimator.ofInt(startHeight,targetHeight);
		animator.addUpdateListener(new AnimatorUpdateListener() {//监听动画数值变化
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				int value=(Integer) animation.getAnimatedValue();
				layoutParams.height=value;
				des_content.setLayoutParams(layoutParams);
				scrollView.scrollTo(0, scrollView.getMeasuredHeight());// 让scrollView 移动到最下面
			}
		});
		animator.addListener(new AnimatorListener() {  // 监听动画执行
			//当动画开始执行的时候调用
			@Override
			public void onAnimationStart(Animator arg0) {
				// TODO Auto-generated method stub
				
			}
			@Override
			public void onAnimationRepeat(Animator arg0) {
				
			}
			@Override
			public void onAnimationEnd(Animator arg0) {
				if(flag){
					des_arrow.setImageResource(R.drawable.arrow_up);
				}else{
					des_arrow.setImageResource(R.drawable.arrow_down);
				}
			}
			@Override
			public void onAnimationCancel(Animator arg0) {
				
			}
		});
		animator.setDuration(500);//设置动画持续时间
		animator.start();
	}
}	


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值