主页面的页面切换,使用了MyFragmentTabHost
进行切换,首先建立五个MianTab,依次创建VIew添加进去;
开源中国源码学习UI篇(一)之FragmentTabHost的使用分析
public enum MainTab {
NEWS(0, "综合", R.drawable.tab_icon_new,
NewsViewPagerFragment.class),
TWEET(1, "动弹", R.drawable.tab_icon_tweet,
TweetsViewPagerFragment.class),
QUICK(2, "快速", R.drawable.tab_icon_new,
null),
EXPLORE(3, "发现", R.drawable.tab_icon_explore,
ExploreFragment.class),
ME(4, "我", R.drawable.tab_icon_me,
MyInformationFragment.class);
private int idx;
private int resName;
private int resIcon;
private Class<?> clz;
private MainTab(int idx, int resName, int resIcon, Class<?> clz) {
this.idx = idx;
this.resName = resName;
this.resIcon = resIcon;
this.clz = clz;
}
}
封装基类
1.封装上层基类
综合界面
Fragement
<-BaseFragment
<-BaseViewPagerFragment
<-NewsFragment
2.放入缓存列表
BaseApplication.java
/**
* 放入已读文章列表中
*
*/
public static void putReadedPostList(String prefFileName, String key,
String value) {
SharedPreferences preferences = getPreferences(prefFileName);
int size = preferences.getAll().size();
Editor editor = preferences.edit();
if (size >= 100) {
editor.clear();
}
editor.putString(key, value);
apply(editor);
}
读取已读文章
/**
* 读取是否是已读的文章列表
*
* @return
*/
public static boolean isOnReadedPostList(String prefFileName, String key) {
return getPreferences(prefFileName).contains(key);
}
3.是否到时间刷新数据
// 是否到时间去刷新数据了
private boolean onTimeRefresh() {
String lastRefreshTime = AppContext.getLastRefreshTime(getCacheKey());
String currTime = StringUtils.getCurTimeStr();
long diff = StringUtils.calDateDifferent(lastRefreshTime, currTime);
return needAutoRefresh() && diff > getAutoRefreshTime();
}
4.操作数据库的时候用AsyncTask
网路获取
以NewsFragment的网络获取为例
- 在BaseListFragment写好一个protected的requestData方法实现网络获取:
/**BaseListFragment**/
protected void requestData(boolean refresh) {
String key = getCacheKey();
if (isReadCacheData(refresh)) {
readCacheData(key);
} else {
// 取新的数据
sendRequestData();
}
}
- NewsFragment继承了这个类,复写这个方法,调用网络交互的类进行网络交互
/**NewsFragment继承了这个类,复写这个方法,调用网络交互的类进行网络交互**/
@Override
protected void sendRequestData() {
OSChinaApi.getNewsList(mCatalog, mCurrentPage, mHandler);
}
- 之后mHandler这个对象创建在BaseListFragment,在这里完成网络获取,并开启线程将数据保存数据库
protected AsyncHttpResponseHandler mHandler = new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBytes) {
if (mCurrentPage == 0 && needAutoRefresh()) {
AppContext.putToLastRefreshTime(getCacheKey(),
StringUtils.getCurTimeStr());
}
if (isAdded()) {
if (mState == STATE_REFRESH) {
onRefreshNetworkSuccess();
}
//进行数据的解析
executeParserTask(responseBytes);
}
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2,
Throwable arg3) {
if (isAdded()) {
readCacheData(getCacheKey());
}
}
};
- 其中
executeParserTask(responseBytes)
方法里调用了
private void executeParserTask(byte[] data) {
cancelParserTask();
mParserTask = new ParserTask(data);
mParserTask.execute();
}
- 成功将数据保存进数据库后的操作
class ParserTask extends AsyncTask<Void, Void, String> {
private final byte[] reponseData;
private boolean parserError;
private List<T> list;
public ParserTask(byte[] data) {
this.reponseData = data;
}
@Override
protected String doInBackground(Void... params) {
try {
ListEntity<T> data = parseList(new ByteArrayInputStream(
reponseData));
new SaveCacheTask(getActivity(), data, getCacheKey()).execute();
list = data.getList();
if (list == null) {
ResultBean resultBean = XmlUtils.toBean(ResultBean.class,
reponseData);
if (resultBean != null) {
mResult = resultBean.getResult();
}
}
} catch (Exception e) {
e.printStackTrace();
parserError = true;
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//parserError代表解析错
if (parserError) {
readCacheData(getCacheKey());
} else {
//当没有数据的时候,重新进行网络获取
executeOnLoadDataSuccess(list);
executeOnLoadFinish();
}
}
}
- 数据获取成功后,进行数据展示
protected void executeOnLoadDataSuccess(List<T> data) {
if (data == null) {
data = new ArrayList<T>();
}
if (mResult != null && !mResult.OK()) {
AppContext.showToast(mResult.getErrorMessage());
// 注销登陆,密码已经修改,cookie,失效了
AppContext.getInstance().Logout();
}
mErrorLayout.setErrorType(EmptyLayout.HIDE_LAYOUT);
if (mCurrentPage == 0) {
mAdapter.clear();
}
for (int i = 0; i < data.size(); i++) {
if (compareTo(mAdapter.getData(), data.get(i))) {
data.remove(i);
i--;
}
}
int adapterState = ListBaseAdapter.STATE_EMPTY_ITEM;
if ((mAdapter.getCount() + data.size()) == 0) {
adapterState = ListBaseAdapter.STATE_EMPTY_ITEM;
} else if (data.size() == 0
|| (data.size() < getPageSize() && mCurrentPage == 0)) {
adapterState = ListBaseAdapter.STATE_NO_MORE;
mAdapter.notifyDataSetChanged();
} else {
adapterState = ListBaseAdapter.STATE_LOAD_MORE;
}
mAdapter.setState(adapterState);
mAdapter.addData(data);
// 判断等于是因为最后有一项是listview的状态
if (mAdapter.getCount() == 1) {
if (needShowEmptyNoData()) {
mErrorLayout.setErrorType(EmptyLayout.NODATA);
} else {
mAdapter.setState(ListBaseAdapter.STATE_EMPTY_ITEM);
mAdapter.notifyDataSetChanged();
}
}
}
- 从数据库中读取
private void readCacheData(String cacheKey) {
cancelReadCacheTask();
mCacheTask = new CacheTask(getActivity()).execute(cacheKey);
}
- 读取成功后再次进行数据展示
private class CacheTask extends AsyncTask<String, Void, ListEntity<T>> {
private final WeakReference<Context> mContext;
private CacheTask(Context context) {
mContext = new WeakReference<Context>(context);
}
@Override
protected ListEntity<T> doInBackground(String... params) {
Serializable seri = CacheManager.readObject(mContext.get(),
params[0]);
if (seri == null) {
return null;
} else {
return readList(seri);
}
}
@Override
protected void onPostExecute(ListEntity<T> list) {
super.onPostExecute(list);
if (list != null) {
executeOnLoadDataSuccess(list.getList());
} else {
executeOnLoadDataError(null);
}
executeOnLoadFinish();
}
}
动弹界面
- 支持的人会显示在图片下面
public void setLikeUsers(Context contet, TextView likeUser, boolean limit) {
// 构造多个超链接的html, 通过选中的位置来获取用户名
if (getLikeCount() > 0 && getLikeUser() != null
&& !getLikeUser().isEmpty()) {
likeUser.setVisibility(View.VISIBLE);
likeUser.setMovementMethod(LinkMovementMethod.getInstance());
likeUser.setFocusable(false);
likeUser.setLongClickable(false);
likeUser.setText(addClickablePart(contet, limit), BufferType.SPANNABLE);
} else {
likeUser.setVisibility(View.GONE);
likeUser.setText("");
}
}
- 点赞的操作,显示下列的人
/**
* @return
*/
private SpannableStringBuilder addClickablePart(final Context context,
boolean limit) {
StringBuilder sbBuilder = new StringBuilder();
int showCunt = getLikeUser().size();
if (limit && showCunt > 4) {
showCunt = 4;
}
// 如果已经点赞,始终让该用户在首位
if (getIsLike() == 1) {
for (int i = 0; i < getLikeUser().size(); i++) {
if (getLikeUser().get(i).getId() == AppContext.getInstance()
.getLoginUid()) {
getLikeUser().remove(i);
}
}
getLikeUser().add(0, AppContext.getInstance().getLoginUser());
}
for (int i = 0; i < showCunt; i++) {
sbBuilder.append(getLikeUser().get(i).getName()).append("、");
}
String likeUsersStr = sbBuilder.substring(0, sbBuilder.lastIndexOf("、"));
// 第一个赞图标
// ImageSpan span = new ImageSpan(AppContext.getInstance(),
// R.drawable.ic_unlike_small);
SpannableString spanStr = new SpannableString("");
// spanStr.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
SpannableStringBuilder ssb = new SpannableStringBuilder(spanStr);
ssb.append(likeUsersStr);
String[] likeUsers = likeUsersStr.split("、");
if (likeUsers.length > 0) {
// 最后一个
for (int i = 0; i < likeUsers.length; i++) {
final String name = likeUsers[i];
final int start = likeUsersStr.indexOf(name) + spanStr.length();
final int index = i;
ssb.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
User user = getLikeUser().get(index);
UIHelper.showUserCenter(context, user.getId(),
user.getName());
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// ds.setColor(R.color.link_color); // 设置文本颜色
// 去掉下划线
ds.setUnderlineText(false);
}
}, start, start + name.length(), 0);
}
}
if (likeUsers.length < getLikeCount()) {
ssb.append("等");
int start = ssb.length();
String more = getLikeCount() + "人";
ssb.append(more);
ssb.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
Bundle bundle = new Bundle();
bundle.putInt(BaseListFragment.BUNDLE_KEY_CATALOG, getId());
UIHelper.showSimpleBack(context,
SimpleBackPage.TWEET_LIKE_USER_LIST, bundle);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
// ds.setColor(R.color.link_color); // 设置文本颜色
// 去掉下划线
ds.setUnderlineText(false);
}
}, start, start + more.length(), 0);
return ssb.append("觉得很赞");
} else {
return ssb.append("觉得很赞");
}
}
学习心得:采用了父类的借口回调,在父类创建抽象的方法,利用子类实现,减少了子类的代码编写量。在父类可以封装不同的代码,提高了代码的复用率。在界面跳转的时候进行统一管理,代码也更加简单。