一、HomePictureHolder.java & 使用ViewPager控件完成广告条效果

HomePictureHolder.java
package com.xbmu.google.holder;import java.util.List;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import com.xbmu.google.R;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;public class HomePictureHolder extends BaseHolder<List<String>> {private ViewPager viewPager;private List<String> datas;/* 当new HomePictureHolder()就会调用该方法 */@Overrideprotected 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() 才会调用 */@Overrideprotected void refreshView(List<String> datas) {this.datas = datas;viewPager.setAdapter(new HomePicAdapter());viewPager.setCurrentItem(1000*datas.size());}class HomePicAdapter extends PagerAdapter {/* 当前viewPager里面有多少个条目 */@Overridepublic int getCount() {return Integer.MAX_VALUE;}/* 判断返回的对象和加载view的对象的关系 */@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView((ImageView) object);}@Overridepublic Object instantiateItem(ViewGroup container, int position) {int index = position % datas.size();ImageView imageView = new ImageView(UiUtils.getContext());bitmapUtils.display(imageView, HttpHelper.URL + "image?name="+ datas.get(index));container.addView(imageView);// 加载的view对象return imageView;// 返回的对象}}}
HomeProtocol.java
package com.xbmu.google.protocol;import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.google.domain.AppInfo;
public class HomeProtocol extends BaseProtocol<List<AppInfo>>{private List<String> pictures;@Overrideprotected List<AppInfo> parseJson(String json) {List<AppInfo> appInfos = new ArrayList<AppInfo>();pictures = new ArrayList<String>();try {JSONObject jsonObject = new JSONObject(json);JSONArray array = jsonObject.getJSONArray("picture");for (int i = 0; i < array.length(); i++) {String str = array.getString(i);pictures.add(str);}JSONArray jsonArray = jsonObject.getJSONArray("list");for (int i = 0; i < jsonArray.length(); i++) {JSONObject object = jsonArray.getJSONObject(i);Long id = object.getLong("id");String name = object.getString("name");String packageName = object.getString("packageName");String iconUrl = object.getString("iconUrl");float stars = Float.valueOf(object.getString("stars"));Long size = object.getLong("size");String downloadUrl = object.getString("downloadUrl");String des = object.getString("des");AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl, stars, size, downloadUrl, des);appInfos.add(appInfo);}return appInfos;} catch (JSONException e) {e.printStackTrace();return null;}}@Overrideprotected String getKey() {return "home";}public List<String> getPictures() {return pictures;}}

HomeFragment.java

package com.xbmu.google.fragment;import java.util.List;
import android.os.Bundle;
import android.view.View;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.ListBaseAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.HomePictureHolder;
import com.xbmu.google.protocol.HomeProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;public class HomeFragment extends BaseFragment {private List<AppInfo> mDatas;private List<String> pictures;//顶部ViewPager 显示界面的数据// 当Fragment挂载的activity创建的时候调用@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);show();}@Overrideprotected View createSuccessView() {BaseListView listView = new BaseListView(UiUtils.getContext());HomePictureHolder holder = new HomePictureHolder();holder.setData(pictures);View contentView = holder.getContentView();//得到holder里面管理的view对象listView.addHeaderView(contentView);listView.setAdapter(new ListBaseAdapter(mDatas){@Overrideprotected List<AppInfo> onload() {HomeProtocol protocol = new HomeProtocol();List<AppInfo> load = protocol.load(mDatas.size());mDatas.addAll(load);return load;}});// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载// 第三个参数 飞速滑动的时候是否加载图片 true 不加载listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,false, true));bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片return listView;}@Overrideprotected LoadResult load() {HomeProtocol protocol = new HomeProtocol();mDatas = protocol.load(0);pictures = protocol.getPictures();return checkData(mDatas);}}

dimens.xml

<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>
</resources>

UiUtils.java

package com.xbmu.google.tools;import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.View;
import com.xbmu.google.application.BaseApplication;
public class UiUtils {//....public static int getDimens(int homePictureHeight) {return (int)getResource().getDimension(homePictureHeight);}
}

运行效果图


二、VIewPager的优化

HomePictureHolder.java
package com.xbmu.google.holder;import java.util.LinkedList;
import java.util.List;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import com.xbmu.google.R;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;public class HomePictureHolder extends BaseHolder<List<String>> {private ViewPager viewPager;private List<String> datas;/* 当new HomePictureHolder()就会调用该方法 */@Overrideprotected 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() 才会调用 */@Overrideprotected void refreshView(List<String> datas) {this.datas = datas;viewPager.setAdapter(new HomePicAdapter());viewPager.setCurrentItem(1000*datas.size());}class HomePicAdapter extends PagerAdapter {//ViewPager的优化 仿照ListView优化原理LinkedList<ImageView> convertView = new LinkedList<ImageView>();/* 当前viewPager里面有多少个条目 */@Overridepublic int getCount() {return Integer.MAX_VALUE;}/* 判断返回的对象和加载view的对象的关系 */@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {ImageView view = (ImageView) object;convertView.add(view);//把移除的对象 添加到缓存集合中container.removeView(view);}@Overridepublic 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;// 返回的对象}}}

三、自动轮询

HomePictureHolder.java
package com.xbmu.google.holder;import java.util.LinkedList;
import java.util.List;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;import com.xbmu.google.R;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;public class HomePictureHolder extends BaseHolder<List<String>> {private ViewPager viewPager;private List<String> datas;/* 当new HomePictureHolder()就会调用该方法 */@Overrideprotected View initView() {viewPager = new ViewPager(UiUtils.getContext());viewPager.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,UiUtils.getDimens(R.dimen.home_picture_height)));return viewPager;}private AutoRunTask runTask;/* 当holder.setData() 才会调用 */@Overrideprotected void refreshView(List<String> datas) {this.datas = datas;viewPager.setAdapter(new HomePicAdapter());viewPager.setCurrentItem(1000*datas.size());viewPager.setOnTouchListener(new OnTouchListener() {@Overridepublic 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();default:break;}return false;//viewPager触摸事件  返回值要是false}});runTask = new AutoRunTask();runTask.start();}boolean flag;public class AutoRunTask implements Runnable{@Overridepublic void run() {if(flag){UiUtils.cancel(this);//取消之前的任务int currentItem = viewPager.getCurrentItem();currentItem++;viewPager.setCurrentItem(currentItem);//延迟执行当前的任务UiUtils.postDelayed(this,3000);//递归调用}}public void start(){if(!flag){UiUtils.cancel(this);//取消之前的任务flag = true;UiUtils.postDelayed(this, 3000);//递归调用               }}public void stop(){if(flag){flag = false;UiUtils.cancel(this);}}}class HomePicAdapter extends PagerAdapter {//ViewPager的优化 仿照ListView优化原理LinkedList<ImageView> convertView = new LinkedList<ImageView>();/* 当前viewPager里面有多少个条目 */@Overridepublic int getCount() {return Integer.MAX_VALUE;}/* 判断返回的对象和加载view的对象的关系 */@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {ImageView view = (ImageView) object;convertView.add(view);//把移除的对象 添加到缓存集合中container.removeView(view);}@Overridepublic 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;// 返回的对象}}}

UiUtils.java

package com.xbmu.google.tools;import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.view.View;
import com.xbmu.google.application.BaseApplication;
import com.xbmu.google.holder.HomePictureHolder.AutoRunTask;
public class UiUtils {//..../*** 延迟执行 任务* @param autoRunTask 任务* @param time 延迟的时间*/public static void postDelayed(AutoRunTask autoRunTask, int time) {BaseApplication.getHandler().postDelayed(autoRunTask, time);//调用Runnable里面的run方法}/*** 取消任务* @param autoRunTask*/public static void cancel(Runnable autoRunTask){BaseApplication.getHandler().removeCallbacks(autoRunTask);}
}

运行效果:

四、MenuHolder的创建

menu_holder.xml
<?xml version="1.0" encoding="utf-8"?>
<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"允许孩子是匹配父容器  --><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/image_photo"android:layout_width="55dp"android:layout_height="55dp"android:background="@drawable/bg_photo"android:padding="5dip" /><ImageViewandroid:id="@+id/image_over"android:layout_width="55dp"android:layout_height="55dp"android:src="@drawable/photo_over" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="55dp"android:layout_marginLeft="20dp"android:layout_toRightOf="@id/image_photo"android:gravity="center_vertical" ><TextViewandroid: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" /><TextViewandroid: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 --><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_home"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_home" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_setting"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_setting" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_theme"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_theme" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_scans"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_scans" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_feedback"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_feedback" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_updates"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_updates" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_about"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_about" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /><RelativeLayoutandroid: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" ><ImageViewandroid:id="@+id/ic_exit"android:layout_width="30dp"android:layout_height="30dp"android:layout_centerVertical="true"android:scaleType="fitXY"android:src="@drawable/ic_exit" /><TextViewandroid: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><Viewandroid:layout_width="wrap_content"android:layout_height="1dp"android:layout_marginLeft="15dp"android:layout_marginRight="15dp"android:background="#1a000000" /></LinearLayout></ScrollView>
MainActivity.java
package com.xbmu.google;import android.annotation.SuppressLint;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;import com.xbmu.google.fragment.BaseFragment;
import com.xbmu.google.fragment.FragmentFactory;
import com.xbmu.google.holder.MenuHolder;
import com.xbmu.google.tools.UiUtils;public class MainActivity extends BaseActivity implements OnQueryTextListener {private ActionBarDrawerToggle drawerToggle;private ViewPager mViewPager;private DrawerLayout mDrawerLayout;private PagerTabStrip mPagerTabStrip;private String[] tab_names;//标签的名字private FrameLayout fl_menu;//菜单的根布局@Overridepublic void init() {tab_names = UiUtils.getStringArray(R.array.tab_names);}@Overridepublic void initView() {super.initView();setContentView(R.layout.activity_main);mDrawerLayout = (DrawerLayout) findViewById(R.id.dl);mViewPager = (ViewPager) findViewById(R.id.vp);mPagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_title_strip);// 设置标签下划线的颜色mPagerTabStrip.setTabIndicatorColor(getResources().getColor(R.color.indicatorcolor));// 给ViewPager设置适配器mViewPager.setAdapter(new MainAdapter(getSupportFragmentManager()));mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);BaseFragment createFragment = FragmentFactory.createFragment(position);createFragment.show();//当切换界面的时候,重新请求服务器}});fl_menu = (FrameLayout) findViewById(R.id.fl_menu);MenuHolder holder = new MenuHolder();//之前已经登录过了//holder.setData(data);fl_menu.addView(holder.getContentView());}//....
}

MenuHolder.java

package com.xbmu.google.holder;import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.xbmu.google.R;
import com.xbmu.google.domain.UserInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.manager.ThreadManager;
import com.xbmu.google.protocol.UserProtocol;
import com.xbmu.google.tools.UiUtils;public class MenuHolder extends BaseHolder<UserInfo>{//通过xUtil框架中的注解方法进行UI绑定@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;@Overrideprotected View initView() {View view  =UiUtils.inflate(R.layout.menu_holder);ViewUtils.inject(this, view);//注入view和事件return view;}@Overrideprotected void refreshView(UserInfo data) {}}

运行效果:

五、Menu菜单 & 登录

UserInfo.java
package com.xbmu.google.domain;
/*** 用户信息* @author bitaotao**/
public class UserInfo {private String name;private String url;private String email;//...
}
MenuHolder.java
package com.xbmu.google.holder;import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.xbmu.google.R;
import com.xbmu.google.domain.UserInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.manager.ThreadManager;
import com.xbmu.google.protocol.UserProtocol;
import com.xbmu.google.tools.UiUtils;public class MenuHolder extends BaseHolder<UserInfo> implements OnClickListener {//通过xUtil框架中的注解方法进行UI绑定@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;@Overrideprotected View initView() {View view  =UiUtils.inflate(R.layout.menu_holder);ViewUtils.inject(this, view);//注入view和事件photo_layout.setOnClickListener(this);//设置监听事件return view;}@Overrideprotected void refreshView(UserInfo data) {user_name.setText(data.getName());user_email.setText(data.getEmail());String url = data.getUrl();// image/user.pngbitmapUtils.display(image_photo, HttpHelper.URL+"image?name="+url);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.photo_layout://  链接服务器 ... 登录ThreadManager.getInstance().createLongPool().execute(new Runnable() {@Overridepublic void run() {UserProtocol protocol = new UserProtocol();final UserInfo userInfo  = protocol.load(0);UiUtils.runOnUiThread(new Runnable() {@Overridepublic void run() {setData(userInfo);}});}});break;}}}

UserProtocol.java

package com.xbmu.google.protocol;import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.google.domain.UserInfo;
public class UserProtocol extends BaseProtocol<UserInfo> {@Overrideprotected UserInfo parseJson(String json) {//{name:'小明',email:'xiaoming@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;}}@Overrideprotected String getKey() {return "user";}}

六、条目的点击事件

DefaultAdapter.java
package com.xbmu.google.adapter;import java.util.List;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.MoreHoder;
import com.xbmu.google.manager.ThreadManager;
import com.xbmu.google.tools.UiUtils;public abstract class DefaultAdapter<Data> extends BaseAdapter implements OnItemClickListener {private List<Data> mDatas;private static final int DEFAULT_ITEM = 0;private static final int MORE_ITEM = 1;private ListView listView;public DefaultAdapter(List<Data> mDatas,ListView listView) {this.mDatas = mDatas;//设置ListView的监听事件listView.setOnItemClickListener(this);this.listView = listView;}//listview条目点击事件回调的方法@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {
//      Toast.makeText(UiUtils.getContext(), "position:"+position, 0).show();position = position - listView.getHeaderViewsCount();//获取到顶部条目的数量  位置去掉顶部view的数量onInnerItemClick(position);}/**在该方法去处理条目的点击事件*/public void onInnerItemClick(int position) {}//...
}

ListBaseAdapter.java

package com.xbmu.google.adapter;import java.util.List;
import android.widget.ListView;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.holder.ListBaseHolder;
public abstract class ListBaseAdapter extends DefaultAdapter<AppInfo> {public ListBaseAdapter(List<AppInfo> mDatas,ListView listView) {super(mDatas,listView);}@Overrideprotected BaseHolder<AppInfo> getHolder() {return new ListBaseHolder();}@Overrideprotected abstract List<AppInfo> onload();
}

HomeFragment.java

package com.xbmu.google.fragment;import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.DetailActivity;
import com.xbmu.google.R;
import com.xbmu.google.adapter.ListBaseAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.HomePictureHolder;
import com.xbmu.google.protocol.HomeProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;public class HomeFragment extends BaseFragment {private List<AppInfo> mDatas;private List<String> pictures;//顶部ViewPager 显示界面的数据// 当Fragment挂载的activity创建的时候调用@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);show();}@Overrideprotected View createSuccessView() {BaseListView listView = new BaseListView(UiUtils.getContext());HomePictureHolder holder = new HomePictureHolder();holder.setData(pictures);View contentView = holder.getContentView();//得到holder里面管理的view对象listView.addHeaderView(contentView);//把holder里的view对象  添加到listview的上面listView.setAdapter(new ListBaseAdapter(mDatas,listView){@Overrideprotected List<AppInfo> onload() {HomeProtocol protocol = new HomeProtocol();List<AppInfo> load = protocol.load(mDatas.size());mDatas.addAll(load);return load;}@Overridepublic void onInnerItemClick(int position) {super.onInnerItemClick(position);Toast.makeText(UiUtils.getContext(), "position="+position, 0).show();}});// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载// 第三个参数 飞速滑动的时候是否加载图片 true 不加载listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,false, true));bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片return listView;}//...
}

SubjectFragment.java

package com.xbmu.google.fragment;import java.util.List;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.R;
import com.xbmu.google.adapter.DefaultAdapter;
import com.xbmu.google.domain.SubjectInfo;
import com.xbmu.google.holder.BaseHolder;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.protocol.SubjectProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;public class SubjectFragment extends BaseFragment {private List<SubjectInfo> mDatas;@Overrideprotected View createSuccessView() {BaseListView listView = new BaseListView(UiUtils.getContext());listView.setAdapter(new SubjectAdapter(mDatas,listView));// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载// 第三个参数 飞速滑动的时候是否加载图片 true 不加载listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,false, true));bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片return listView;}private class SubjectAdapter extends DefaultAdapter<SubjectInfo> {public SubjectAdapter(List<SubjectInfo> mDatas,ListView listView) {super(mDatas,listView);}@Overrideprotected BaseHolder<SubjectInfo> getHolder() {return new SubjectHolder();}@Overrideprotected List<SubjectInfo> onload() {SubjectProtocol protocol = new SubjectProtocol();List<SubjectInfo> load= protocol.load(mDatas.size());mDatas.addAll(load);return load;}@Overridepublic void onInnerItemClick(int position) {// TODO Auto-generated method stubsuper.onInnerItemClick(position);}}//....
}

运行效果:

七、切换DetailActivity架子

HomeFragment.java
package com.xbmu.google.fragment;import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.lidroid.xutils.bitmap.PauseOnScrollListener;
import com.xbmu.google.DetailActivity;
import com.xbmu.google.R;
import com.xbmu.google.adapter.ListBaseAdapter;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.HomePictureHolder;
import com.xbmu.google.protocol.HomeProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.BaseListView;
import com.xbmu.google.view.LoadingPage.LoadResult;public class HomeFragment extends BaseFragment {private List<AppInfo> mDatas;private List<String> pictures;//顶部ViewPager 显示界面的数据// 当Fragment挂载的activity创建的时候调用@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);show();}@Overrideprotected View createSuccessView() {BaseListView listView = new BaseListView(UiUtils.getContext());HomePictureHolder holder = new HomePictureHolder();holder.setData(pictures);View contentView = holder.getContentView();//得到holder里面管理的view对象listView.addHeaderView(contentView);//把holder里的view对象  添加到listview的上面listView.setAdapter(new ListBaseAdapter(mDatas,listView){@Overrideprotected List<AppInfo> onload() {HomeProtocol protocol = new HomeProtocol();List<AppInfo> load = protocol.load(mDatas.size());mDatas.addAll(load);return load;}@Overridepublic void onInnerItemClick(int position) {super.onInnerItemClick(position);
//              Toast.makeText(UiUtils.getContext(), "position="+position, 0).show();AppInfo appInfo = mDatas.get(position);Intent intent = new Intent(UiUtils.getContext(), DetailActivity.class);intent.putExtra("packageName", appInfo.getPackageName());startActivity(intent);}});// ListView有三种滑动状态:静止,慢慢滑动,飞速滑动// 第二个参数 慢慢滑动的时候是否加载图片 false 加载 true 不加载// 第三个参数 飞速滑动的时候是否加载图片 true 不加载listView.setOnScrollListener(new PauseOnScrollListener(bitmapUtils,false, true));bitmapUtils.configDefaultLoadingImage(R.drawable.ic_default); // 设置如果图片加载中显示的图片bitmapUtils.configDefaultLoadFailedImage(R.drawable.ic_default);// 加载失败显示的图片return listView;}//...
}

DetailActivity.java

package com.xbmu.google;import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.protocol.DetailProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.LoadingPage;
import com.xbmu.google.view.LoadingPage.LoadResult;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.View;
public class DetailActivity extends BaseActivity {private ActionBar actionBar;private String packageName;private AppInfo data;@Overridepublic void initView() {LoadingPage loadingPage = new LoadingPage(UiUtils.getContext()) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overrideprotected View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show();setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent();//获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}/*** 加载成功的界面* @return*/protected View createSuccessView() {// TODO Auto-generated method stubreturn null;}/*** 请求服务器加载数据* @return*/protected LoadResult load() {DetailProtocol protocol = new DetailProtocol(packageName);data = protocol.load(0);if(data==null){return LoadResult.ERROR;}else{return LoadResult.SUCCESS;}}@Overridepublic void init() {super.init();}@Overridepublic void initActionBar() {super.initActionBar();actionBar = getSupportActionBar();actionBar.setDisplayHomeAsUpEnabled(true);}
}

BaseProtocol.java

package com.xbmu.google.protocol;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import android.os.SystemClock;
import com.lidroid.xutils.util.IOUtils;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.http.HttpHelper.HttpResult;
import com.xbmu.google.tools.FileUtils;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 parseJson(json);}else{return null;}}protected abstract T parseJson(String json);/*** 将json文件保存到本地* @param json* @param index*/private void saveLocal(String json, int index) {BufferedWriter bw = null;try {File dir = FileUtils.getCacheDir();//在第一行写一个过期时间File file = new File(dir, getKey()+"_"+index);// /mnt/sdcard/googlePlay/cache/home_0FileWriter 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 (IOException e) {e.printStackTrace();}  finally{IOUtils.closeQuietly(bw);}}protected  abstract  String getKey();private String loadServer(int index) {HttpResult httpResult = HttpHelper.get(HttpHelper.URL+getKey()+"?index="+index+getParams());//  http://127.0.0.1:8090/home?index=indexif(httpResult!=null){String json = httpResult.getString();return json;}return null;}/*** 额外带的参数* @return*/protected String getParams() {return "";}/*** 加载本地json文件(读取本地文件)* @param index* @return*/private String loadLocal(int index) {//如果发现文件已经过期了,就不要再去复用缓存了File dir = FileUtils.getCacheDir();//获取缓存所在的文件夹File file = new File(dir, getKey()+"_"+index);try {FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);Long outOfDate = Long.valueOf(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 (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return null;}
}

DetailProtocol.java

package com.xbmu.google.protocol;import com.xbmu.google.domain.AppInfo;public class DetailProtocol extends BaseProtocol<AppInfo> {private String packageName;public DetailProtocol(String packageName) {super();this.packageName = packageName;}@Overrideprotected AppInfo parseJson(String json) {// TODO Auto-generated method stubreturn null;}@Overrideprotected String getKey() {return "detail";}@Overrideprotected String getParams() {return "&packageName="+packageName;}
}

八、Detail界面的数据解析

DetailProtocol.java
package com.xbmu.google.protocol;import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xbmu.google.domain.AppInfo;public class DetailProtocol extends BaseProtocol<AppInfo> {private String packageName;public DetailProtocol(String packageName) {super();this.packageName = packageName;}@Overrideprotected AppInfo parseJson(String json) {try {JSONObject jsonObject = new JSONObject(json);Long id = jsonObject.getLong("id");String name = jsonObject.getString("name");String packageName = jsonObject.getString("packageName");String iconUrl = jsonObject.getString("iconUrl");float stars = Float.valueOf(jsonObject.getString("stars"));String downloadNum = jsonObject.getString("downloadNum");String version = jsonObject.getString("version");String date = jsonObject.getString("date");Long size = jsonObject.getLong("size");String downloadUrl = jsonObject.getString("downloadUrl");String des = jsonObject.getString("des");String author = jsonObject.getString("author");List<String> screenList = new ArrayList<String>();JSONArray jsonArray = jsonObject.getJSONArray("screen");for (int i = 0; i < jsonArray.length(); i++) {String screenUrl = jsonArray.getString(i);screenList.add(screenUrl);}List<String> safeUrlList = new ArrayList<String>();List<String> safeDesurlList = new ArrayList<String>();List<String> safeDesList = new ArrayList<String>();List<Integer> safeDesColorList = new ArrayList<Integer>();JSONArray safeList = jsonObject.getJSONArray("safe");for (int i = 0; i < safeList.length(); i++) {JSONObject object = safeList.getJSONObject(i);String safeUrl = object.getString("safeUrl");String safeDesUrl = object.getString("safeDesUrl");String safeDes = object.getString("safeDes");String safeDesColor = object.getString("safeDesColor");safeUrlList.add(safeUrl);safeDesurlList.add(safeDesUrl);safeDesList.add(safeDes);safeDesColorList.add(Integer.valueOf(safeDesColor));}AppInfo appInfo = new AppInfo(id, name, packageName, iconUrl,stars, size, downloadUrl, des, downloadNum, version, date,author, screenList, safeUrlList, safeDesurlList, safeDesList, safeDesColorList);return appInfo;} catch (JSONException e) {e.printStackTrace();return null;}}@Overrideprotected String getKey() {return "detail";}@Overrideprotected String getParams() {return "&packageName=" + packageName;}
}

九、通过Holder显示界面

activity_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><FrameLayoutandroid:id="@+id/bottom_layout"android:layout_width="match_parent"android:layout_height="50dp"android:layout_alignParentBottom="true"android:background="@drawable/detail_bottom_bg" ></FrameLayout><ScrollViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/bottom_layout"android:layout_marginBottom="5dp"android:fillViewport="true" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent" ><FrameLayoutandroid: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" /><FrameLayoutandroid: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" /><HorizontalScrollViewandroid: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" /><FrameLayoutandroid: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>

DetailActivity.java

package com.xbmu.google;import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.DetailInfoHolder;
import com.xbmu.google.protocol.DetailProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.LoadingPage;
import com.xbmu.google.view.LoadingPage.LoadResult;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
public class DetailActivity extends BaseActivity {private ActionBar actionBar;private String packageName;private AppInfo data;@Overridepublic void initView() {LoadingPage loadingPage = new LoadingPage(UiUtils.getContext()) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overrideprotected View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show();setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent();//获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}private FrameLayout bottom_layout,detail_info,detail_safe,detail_des;private HorizontalScrollView detail_screen;private DetailInfoHolder detailInfoHolder;/*** 加载成功的界面* @return*/protected View createSuccessView() {View view = UiUtils.inflate(R.layout.activity_detail);//添加信息区域bottom_layout = (FrameLayout) view.findViewById(R.id.bottom_layout);//操作应用程序信息detail_info = (FrameLayout) view.findViewById(R.id.detail_info);detailInfoHolder = new DetailInfoHolder();detailInfoHolder.setData(data);detail_info.addView(detailInfoHolder.getContentView());detail_safe = (FrameLayout) view.findViewById(R.id.detail_safe);detail_des = (FrameLayout) view.findViewById(R.id.detail_des);detail_screen = (HorizontalScrollView) view.findViewById(R.id.detail_screen);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;}}@Overridepublic void init() {super.init();}@Overridepublic void initActionBar() {super.initActionBar();actionBar = getSupportActionBar();actionBar.setDisplayHomeAsUpEnabled(true);}
}

DetailInfoHolder.java

package com.xbmu.google.holder;import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.tools.UiUtils;
import android.view.View;
import android.widget.TextView;public class DetailInfoHolder extends BaseHolder<AppInfo> {private TextView tv;/***实例化控件和布局 */@Overrideprotected View initView() {tv = new TextView(UiUtils.getContext());return tv;}@Overrideprotected void refreshView(AppInfo data) {tv.setText(data.getName());}
}
运行效果图:
DetailActivity.java和DetailInfoHolder.java方法之间的调用关系

十、应用详情&应用图片

detail_app_info.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/item_info_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp" ><RelativeLayoutandroid:id="@+id/item_top"android:layout_width="match_parent"android:layout_height="wrap_content" ><ImageViewandroid: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" /><RelativeLayoutandroid:id="@+id/item_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_toRightOf="@id/item_icon" ><TextViewandroid: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" /><RatingBarandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/item_top"android:orientation="vertical" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:orientation="horizontal" ><TextViewandroid: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" /><TextViewandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:orientation="horizontal" ><TextViewandroid: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" /><TextViewandroid: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></RelativeLayout>
dimens.xml
<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>

DetailInfoHolder.java

package com.xbmu.google.holder;import android.text.format.Formatter;
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;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;/***实例化控件和布局 */@Overrideprotected View initView() {View view = UiUtils.inflate(R.layout.detail_app_info);ViewUtils.inject(this, view);return view;}@Overrideprotected 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()));}}

detail_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content" ><ImageViewandroid:id="@+id/screen_1"android:layout_width="90dp"android:layout_height="150dp"android:paddingRight="5dp"android:scaleType="fitXY"android:src="@drawable/ic_default" /><ImageViewandroid: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" /><ImageViewandroid: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" /><ImageViewandroid: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" /><ImageViewandroid: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>

DetailScreenHolder.java

package com.xbmu.google.holder;import java.util.List;
import android.view.View;
import android.widget.ImageView;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;public class DetailScreenHolder extends BaseHolder<AppInfo> {ImageView[] ivs;@Overrideprotected 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;}@Overrideprotected void refreshView(AppInfo data) {List<String> screen = data.getScreen();//集合的大小有可能小于5for (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);}}}
}

BaseProtocol.java

package com.xbmu.google.protocol;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import android.os.SystemClock;
import com.lidroid.xutils.util.IOUtils;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.http.HttpHelper.HttpResult;
import com.xbmu.google.tools.FileUtils;public abstract class BaseProtocol<T> {//..../*** 将json文件保存到本地* @param json* @param index*/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_0FileWriter 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 (IOException e) {e.printStackTrace();}  finally{IOUtils.closeQuietly(bw);}}//....
}

DetailActivity.java

package com.xbmu.google;import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.DetailInfoHolder;
import com.xbmu.google.holder.DetailScreenHolder;
import com.xbmu.google.protocol.DetailProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.LoadingPage;
import com.xbmu.google.view.LoadingPage.LoadResult;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
public class DetailActivity extends BaseActivity {private ActionBar actionBar;private String packageName;private AppInfo data;@Overridepublic void initView() {LoadingPage loadingPage = new LoadingPage(UiUtils.getContext()) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overrideprotected View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show();setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent();//获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}private FrameLayout bottom_layout,detail_info,detail_safe,detail_des;private HorizontalScrollView detail_screen;private DetailInfoHolder detailInfoHolder;private DetailScreenHolder screenHolder;/*** 加载成功的界面* @return*/protected View createSuccessView() {View view = UiUtils.inflate(R.layout.activity_detail);//添加信息区域bottom_layout = (FrameLayout) view.findViewById(R.id.bottom_layout);//操作应用程序信息detail_info = (FrameLayout) view.findViewById(R.id.detail_info);detailInfoHolder = new DetailInfoHolder();detailInfoHolder.setData(data);detail_info.addView(detailInfoHolder.getContentView());detail_safe = (FrameLayout) view.findViewById(R.id.detail_safe);detail_des = (FrameLayout) view.findViewById(R.id.detail_des);detail_screen = (HorizontalScrollView) view.findViewById(R.id.detail_screen);screenHolder = new DetailScreenHolder();screenHolder.setData(data);detail_screen.addView(screenHolder.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;}}@Overridepublic void init() {super.init();}@Overridepublic void initActionBar() {super.initActionBar();actionBar = getSupportActionBar();actionBar.setDisplayHomeAsUpEnabled(true);}
}

运行效果图:

十一、应用详安全界面

detail_safe.xml
<?xml version="1.0" encoding="utf-8"?>
<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" ><RelativeLayoutandroid:id="@+id/safe_title_layout"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_vertical" ><LinearLayoutandroid:id="@+id/safe_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:orientation="horizontal" ><ImageViewandroid:id="@+id/iv_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerInside" /><ImageViewandroid:id="@+id/iv_2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:scaleType="centerInside" /><ImageViewandroid:id="@+id/iv_3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:scaleType="centerInside" /><ImageViewandroid:id="@+id/iv_4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:scaleType="centerInside" /></LinearLayout><ImageViewandroid: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><LinearLayoutandroid:id="@+id/safe_content"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/safe_title_layout"android:orientation="vertical" ><LinearLayoutandroid: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" ><ImageViewandroid:id="@+id/des_iv_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerInside" /><TextViewandroid: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><LinearLayoutandroid: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" ><ImageViewandroid:id="@+id/des_iv_2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerInside" /><TextViewandroid: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><LinearLayoutandroid: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" ><ImageViewandroid:id="@+id/des_iv_3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerInside" /><TextViewandroid: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><LinearLayoutandroid: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" ><ImageViewandroid:id="@+id/des_iv_4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scaleType="centerInside" /><TextViewandroid: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>

DetailSafeHolder.java

package com.xbmu.google.holder;import java.util.List;import android.graphics.Color;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;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;ImageView[] ivs;ImageView[] iv_des;TextView[] tv_des;LinearLayout[] des_layout;@Overrideprotected 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);return view;}@Overrideprotected 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();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);}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;//flase 显示安全内容  true不显示安全内容@Overridepublic void onClick(View v) {if(v.getId() == R.id.safe_layout){if(!flag){flag = true;safe_content.setVisibility(View.VISIBLE);}else{flag = false;safe_content.setVisibility(View.GONE);}}}}
运行效果:
通过观察详情页面中安全部分信息时,点击箭头的展开和回收,没有动画效果,速度很快,给用户的体验效果不好。

十二、值动画

导入jar包
DetailSafeHolder.java
package com.xbmu.google.holder;import java.util.List;
import android.graphics.Color;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.http.HttpHelper;
import com.xbmu.google.tools.UiUtils;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;@Overrideprotected 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;}@Overrideprotected 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();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);}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;//flase 显示安全内容  true不显示安全内容@Overridepublic 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;}final ValueAnimator animator = ValueAnimator.ofInt(startHeight,targetheight);final RelativeLayout.LayoutParams layoutParams = (android.widget.RelativeLayout.LayoutParams) safe_content.getLayoutParams();animator.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator arg0) {int value = (Integer) animator.getAnimatedValue();//运行当前时间点的一个值layoutParams.height = value;safe_content.setLayoutParams(layoutParams);System.out.println(value);}});animator.addListener(new AnimatorListener() {@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animator arg0) {if(flag){safe_arrow.setImageResource(R.drawable.arrow_up);}else{safe_arrow.setImageResource(R.drawable.arrow_down);}}@Overridepublic void onAnimationCancel(Animator arg0) {// TODO Auto-generated method stub}});animator.setDuration(500);animator.start();}}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+sizeint heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.AT_MOST, 1000);//让高度包裹内容//测量规则  宽度是一个精确的值 width,高度最大是1000,以实际为准safe_content.measure(widthMeasureSpec, heightMeasureSpec);return safe_content.getMeasuredHeight();}
}

运行效果:

十三、描述界面的值动画

detail_des.xml
<?xml version="1.0" encoding="utf-8"?>
<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" ><TextViewandroid: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" /><TextViewandroid: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" /><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/des_content"android:layout_marginTop="5dp"android:gravity="center_vertical" ><TextViewandroid: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" /><ImageViewandroid: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>

DetailDesHolder.java

package com.xbmu.google.holder;import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.tools.UiUtils;public class DetailDesHolder extends BaseHolder<AppInfo> implements OnClickListener {@ViewInject(R.id.des_titile)private TextView des_titile;@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;@Overrideprotected View initView() {View view = UiUtils.inflate(R.layout.detail_des);ViewUtils.inject(this, view);return view;}@Overrideprotected 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);//设置字体大小14dptextView.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();}@Overridepublic void onClick(View v) {expand();}boolean flag = false;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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {int value = (Integer)animation.getAnimatedValue();layoutParams.height = value;des_content.setLayoutParams(layoutParams);}});animator.addListener(new AnimatorListener() {//监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animator arg0) {if(flag){des_arrow.setImageResource(R.drawable.arrow_up);}else{des_arrow.setImageResource(R.drawable.arrow_down);                    }}@Overridepublic void onAnimationCancel(Animator arg0) {// TODO Auto-generated method stub}});animator.setDuration(500);//设置动画持续时间animator.start();}
}

运行效果图:

十四、描述界面细节的处理

DetailDesHolder.java
package com.xbmu.google.holder;import android.util.TypedValue;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.xbmu.google.R;
import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.tools.UiUtils;public class DetailDesHolder extends BaseHolder<AppInfo> implements OnClickListener {@ViewInject(R.id.des_titile)private TextView des_titile;@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;@Overrideprotected View initView() {View view = UiUtils.inflate(R.layout.detail_des);ViewUtils.inject(this, view);return view;}@Overrideprotected 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);//设置字体大小14dptextView.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();}@Overridepublic void onClick(View v) {expand();}ScrollView scrollView;/*** 获取到界面的ScrollView* @param view* @return*/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;}}boolean flag = false;//true展开了 false没有展开private void expand() {scrollView = getScrollView(des_content);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() {@Overridepublic 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() {//监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationEnd(Animator arg0) {if(flag){des_arrow.setImageResource(R.drawable.arrow_up);}else{des_arrow.setImageResource(R.drawable.arrow_down);                   }}@Overridepublic void onAnimationCancel(Animator arg0) {// TODO Auto-generated method stub}});animator.setDuration(500);//设置动画持续时间animator.start();}
}

DetailActivity.java

package com.xbmu.google;import com.xbmu.google.domain.AppInfo;
import com.xbmu.google.holder.DetailDesHolder;
import com.xbmu.google.holder.DetailInfoHolder;
import com.xbmu.google.holder.DetailSafeHolder;
import com.xbmu.google.holder.DetailScreenHolder;
import com.xbmu.google.protocol.DetailProtocol;
import com.xbmu.google.tools.UiUtils;
import com.xbmu.google.view.LoadingPage;
import com.xbmu.google.view.LoadingPage.LoadResult;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
public class DetailActivity extends BaseActivity {private ActionBar actionBar;private String packageName;private AppInfo data;@Overridepublic void initView() {LoadingPage loadingPage = new LoadingPage(UiUtils.getContext()) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overrideprotected View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show();setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent();//获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}private FrameLayout bottom_layout,detail_info,detail_safe,detail_des;private HorizontalScrollView detail_screen;private DetailInfoHolder detailInfoHolder;private DetailScreenHolder screenHolder;private DetailSafeHolder detailSafeHolder;private DetailDesHolder detailDesHolder;/*** 加载成功的界面* @return*/protected View createSuccessView() {View view = UiUtils.inflate(R.layout.activity_detail);//添加信息区域bottom_layout = (FrameLayout) view.findViewById(R.id.bottom_layout);//操作应用程序信息detail_info = (FrameLayout) view.findViewById(R.id.detail_info);detailInfoHolder = new DetailInfoHolder();detailInfoHolder.setData(data);detail_info.addView(detailInfoHolder.getContentView());//安全标记detail_safe = (FrameLayout) view.findViewById(R.id.detail_safe);detailSafeHolder = new DetailSafeHolder();detailSafeHolder.setData(data);detail_safe.addView(detailSafeHolder.getContentView());detail_des = (FrameLayout) view.findViewById(R.id.detail_des);detailDesHolder = new DetailDesHolder();detailDesHolder.setData(data);detail_des.addView(detailDesHolder.getContentView());//中间5张图片detail_screen = (HorizontalScrollView) view.findViewById(R.id.detail_screen);screenHolder = new DetailScreenHolder();screenHolder.setData(data);detail_screen.addView(screenHolder.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;}}@Overridepublic void init() {super.init();}@Overridepublic void initActionBar() {super.initActionBar();actionBar = getSupportActionBar();actionBar.setDisplayHomeAsUpEnabled(true);}
}

运行效果图:

全部代码:
http://download.csdn.net/detail/btt2013/9373854

谷歌电子市场学习笔记第四天相关推荐

  1. 谷歌电子市场学习笔记第三天

    一.抽取DefaultAdapter & BaseHolder 1 .抽取Adapter 共性的方法 . 2. 把getView方法里 和holder相关的逻辑 摘取到Holder代码中 . ...

  2. 吴恩达深度学习笔记(四)

    吴恩达深度学习笔记(四) 卷积神经网络CNN-第二版 卷积神经网络 深度卷积网络:实例探究 目标检测 特殊应用:人脸识别和神经风格转换 卷积神经网络编程作业 卷积神经网络CNN-第二版 卷积神经网络 ...

  3. ASP.NET Core 2 学习笔记(四)依赖注入

    原文:ASP.NET Core 2 学习笔记(四)依赖注入 ASP.NET Core使用了大量的依赖注入(Dependency Injection, DI),把控制反转(Inversion Of Co ...

  4. Spring Cloud 学习笔记(四)-Spring Cloud Hystrix

    Spring Cloud 学习笔记(四)-Spring Cloud Hystrix 由于前一阵子项目的原因,今天才继续弄上,今天想学习一下Hystrix组件 这个组件还挺抽象的,最开始我一直没太明白, ...

  5. OpenCV学习笔记(四十六)——FAST特征点检测features2D OpenCV学习笔记(四十七)——VideoWriter生成视频流highgui OpenCV学习笔记(四十八)——PCA算

    OpenCV学习笔记(四十六)--FAST特征点检测features2D 特征点检测和匹配是计算机视觉中一个很有用的技术.在物体检测,视觉跟踪,三维常年关键等领域都有很广泛的应用.这一次先介绍特征点检 ...

  6. OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co

    OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...

  7. Windows x64内核学习笔记(四)—— 9-9-9-9-12分页

    Windows x64内核学习笔记(四)-- 9-9-9-9-12分页 前言 9-9-9-9-12分页 实验一:线性地址转物理地址 页表基址 定位基址 PTE to PXE 实验二:通过页表基址定位各 ...

  8. Intel VT学习笔记(四)—— VMCS(下)

    Intel VT学习笔记(四)-- VMCS(下) 要点回顾 VM-Exit Information Guest state fields 代码实现 参考资料 要点回顾 在上一篇中,我们了解了如何设置 ...

  9. 软件调试学习笔记(四)—— 异常的处理流程

    软件调试学习笔记(四)-- 异常的处理流程 要点回顾 异常的处理流程 实验1:理解调试器与异常的关系 未处理异常:最后一道防线 实验2:理解UnhandledExceptionFilter执行流程 实 ...

最新文章

  1. PyCharm:选择内容多个光标解决办法
  2. andpods授权码订单号分享_不要再让你的接口裸奔了,Boot快速尝试OAuth2密码和授权码模式...
  3. Flutter中关键字Const和Final之间的区别
  4. Jack Dorsey首条推文NFT的买家在伊朗被捕
  5. 【转载】MySQL -- SET NAMES utf8
  6. 绝缘端子行业调研报告 - 市场现状分析与发展前景预测
  7. UVA12290 Counting Game【数学模拟】
  8. Linux学习笔记 -- 实用指令
  9. Linux kmalloc/kfree 源码解读
  10. Unity3D开发环境的搭建
  11. mysql pxc集群 原理 (图解+秒懂+史上最全)
  12. 《未来世界的幸存者》摘录
  13. 快手:星星之火,寒冬燎原
  14. BUAA 1489
  15. Java中线程同步锁和互斥锁有啥区别?看完你还是一脸懵逼?
  16. NVIDIA、CUDA、CUDNN、PyTorch安装吐血整理!!!
  17. 送给你的一份英语学习资料,请查收!
  18. Prometheus告警实践
  19. JavaScript奇淫技巧:隐写术
  20. php7 三元运算 精简

热门文章

  1. Python 中将列表中的每个元素除以一个数字
  2. python新建数值_1.3NumPy:创建和操作数值数据
  3. linux 用户密码加密
  4. 试用期工作总结(官方版)
  5. PatchmatchNet理解与学习
  6. 基于灰狼优化算法的TSP搜索算法
  7. PPT怎样另存为?是否有快捷键?
  8. 托福百日冲刺—词汇(11)
  9. MPLS 高级应用 sham-link
  10. 黑苹果 10.15 catalina 因特尔蓝牙驱动