谷歌应用市场4
来源:互联网 发布:淘宝酒仙网 编辑:程序博客网 时间:2024/05/09 21:38
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;@Overridepublic 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 才会调用 */@Overridepublic 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@Overridepublic int getCount() {returnInteger.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; // 返回的对象}}}
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 才会调用 */@Overridepublic void refreshView(List<String> datas) {this.datas = datas;viewPager.setAdapter(new HomeAdapter());viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置 Integer.Max_Vlue/2viewPager.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();break;}return false; // viewPager 触摸事件 返回值要是false }});runTask = new AuToRunTask();runTask.start();}boolean flag;private AuToRunTask runTask;public class AuToRunTask implements Runnable{@Overridepublic 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;@Overridepublic 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 才会调用 */@Overridepublic void refreshView(List<String> datas) {this.datas = datas;viewPager.setAdapter(new HomeAdapter());viewPager.setCurrentItem(2000*datas.size());// 设置起始的位置 Integer.Max_Vlue/2viewPager.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();break;}return false; // viewPager 触摸事件 返回值要是false }});runTask = new AuToRunTask();runTask.start();}boolean flag;private AuToRunTask runTask;public class AuToRunTask implements Runnable{@Overridepublic 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@Overridepublic int getCount() {returnInteger.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; // 返回的对象}}}
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> {@Overridepublic 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;}}@Overridepublic 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;@Overridepublic View initView() {View view=UiUtils.inflate(R.layout.menu_holder);ViewUtils.inject(this, view);photo_layout.setOnClickListener(this);return view;}@Overridepublic 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 load = protocol.load(0);UiUtils.runOnUiThread(new Runnable() {@Overridepublic 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 条目点击事件回调的方法@Overridepublic 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){@Overrideprotected List<AppInfo> onload() {HomeProtocol protocol=new HomeProtocol();List<AppInfo> load = protocol.load(datas.size());datas.addAll(load);return load;}@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void run() {SystemClock.sleep(500);final LoadResult result = load();UiUtils.runOnUiThread(new Runnable() {@Overridepublic 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;}@Overridepublic 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;}}@Overridepublic String getKey() {return "detail";}@Overrideprotected 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;}@Overridepublic 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);
接收
@Overrideprotected 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;@Overrideprotected void initView() {LoadingPage loadingPage=new LoadingPage(this) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overridepublic View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show(); // 必须调用show方法 才会请求服务器 加载新的界面setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent(); // 获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}@Overrideprotected 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;@Overrideprotected void initView() {LoadingPage loadingPage = new LoadingPage(this) {@Overrideprotected LoadResult load() {return DetailActivity.this.load();}@Overridepublic View createSuccessView() {return DetailActivity.this.createSuccessView();}};loadingPage.show(); // 必须调用show方法 才会请求服务器 加载新的界面setContentView(loadingPage);}@Overrideprotected void onCreate(Bundle savedInstanceState) {Intent intent = getIntent(); // 获取到打开当前activity的意图对象packageName = intent.getStringExtra("packageName");super.onCreate(savedInstanceState);}@Overrideprotected 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;@Overridepublic View initView() {View view=Uiutils.inflate(R.layout.detals_app_info);ViewUtils.inject(this, view);return view;}@Overridepublic 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;@Overridepublic 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;}@Overridepublic 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_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 (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;@Overridepublic 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;}@Overridepublic 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 3for (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 {@Overrideprotected 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() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {int value=(Integer) animation.getAnimatedValue(); // 当前时间点变化后的值System.out.println(value);}});animator.setDuration(500);animator.start();}@Overridepublic 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+sizeint 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() { // 监听值的变化@Overridepublic 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() { // 监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {}@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) {}});
4.完整
public class DetailSafeHolder extends BaseHolder<AppInfo> implementsOnClickListener {@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;@Overridepublic 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;}@Overridepublic 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 3for (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;@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;}// 值动画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 animator) {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) {}@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) {}});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+sizeint 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);//设置字体大小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();}
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() {//监听动画数值变化@Overridepublic 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() { // 监听动画执行//当动画开始执行的时候调用@Overridepublic void onAnimationStart(Animator arg0) {// TODO Auto-generated method stub}@Overridepublic void onAnimationRepeat(Animator arg0) {}@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) {}});
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;@Overridepublic View initView() {View view=UiUtils.inflate(R.layout.detail_des);ViewUtils.inject(this, view);return view;}@Overridepublic 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();}boolean flag;// true展开了 false 没有展开@Overridepublic 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() {//监听动画数值变化@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) {}@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) {}});animator.setDuration(500);//设置动画持续时间animator.start();}}
- 谷歌应用市场4
- 谷歌应用市场1
- 谷歌应用市场2
- 谷歌应用市场3
- 谷歌应用市场5
- 谷歌应用市场6
- 应用市场
- 谷歌应用市场(谷歌商店google play)应用下载到电脑
- 谷歌市场爬虫
- 谷歌市场发布
- 谷歌市场应用的多apk发布(减小apk的大小)
- 柠檬市场及其应用
- 硝烟中的应用市场
- 打开应用市场代码
- 第三方应用市场
- 应用市场大全
- 跳转应用市场评分
- 应用市场地址
- print_exit_status
- android环境变量的配置
- PostgreSQL cluster table using index
- [python] scapy模块的使用
- mysql事务
- 谷歌应用市场4
- 索引的作用和为什么要创建索引
- 清理ambari安装的hadoop集群
- 二维数组顺时针打印
- JAVA设计模式(10) —<结构型>桥接模式(Bridge)
- 北航上机测试准备 程序1
- select2插件的disabled功能详解
- Java程序初始化顺序
- 如何在高并发分布式系统中生成全局唯一Id