星座物语APP
效果图:

这里的后台管理用的是duducat,大家可以去百度看说明。图片,文字都在duducat后台服务器上,可以自己修改的。(PS:图片这里是随便找的)
我就直接上代码了,如果有不懂的可以联系我。
MainActivity.java
public class MainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener {
private TabHost tabHost;
private HorizontalScrollView hScrollView;
private ViewPager viewPager;
private PagerAdapter pagerAdapter;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, TabInfo>();
/**
* tab顶部标签的基本信息
*/
private class TabInfo {
private String tag;
public View On;
public View Off;
public View Tab;
public TabInfo(String tag, Class<?> clazz, Bundle args) {
this.tag = tag;
}
}
public class TabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public TabFactory(Context context) {
mContext = context;
}
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
protected void onCreate(Bundle savedInstanceState) {
//注册嘟嘟猫后台管理
ActiveConfig.register(MainActivity.this, "19K3Me8Z", "hVAjCHK55TaB66YR");
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hScrollView = (HorizontalScrollView) findViewById(R.id.hScrollView);
//初始化viewpager
initViewPager();
//初始化tabhost
initTabHost(savedInstanceState);
}
protected void onSaveInstanceState(Bundle outState) {
outState.putString("tab", tabHost.getCurrentTabTag());
super.onSaveInstanceState(outState);
}
private void initViewPager() {
//封装Fragment对象
List<Fragment> fragments = new Vector<Fragment>();
for (int i = 0; i < 12; i++) {
Bundle budle = new Bundle();
budle.putInt("i", i);
Fragment f = Fragment.instantiate(MainActivity.this, HoroscopeFragment.class.getName(), budle);
fragments.add(f);
}
pagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(pagerAdapter);
viewPager.setOnPageChangeListener(this);
}
@Override
public void onPageScrolled(int i, float v, int i2) {
}
@Override
public void onPageSelected(int i) {
this.tabHost.setCurrentTab(i);
}
@Override
public void onPageScrollStateChanged(int i) {
}
private void initTabHost(Bundle args) {
tabHost = (TabHost) findViewById(android.R.id.tabhost);
tabHost.setup();//初始化tabhost
TabInfo tabInfo = null;
for (int i = 0; i < 12; i++) {
TabHost.TabSpec tabSpec = this.tabHost.newTabSpec("Tab" + i);
tabSpec.setContent(new TabFactory(this));
View tabView = LayoutInflater.from(tabHost.getContext()).inflate(R.layout.tab_layout, null);
//获得本地图片路径
int resID = getResources().getIdentifier("a" + (i + 1) + "_0", "drawable", getPackageName());
((ImageView) tabView.findViewById(R.id.on)).setImageDrawable(getResources().getDrawable(resID));
resID = getResources().getIdentifier("a" + (i + 1) + "_1", "drawable", getPackageName());
((ImageView) tabView.findViewById(R.id.off)).setImageDrawable(getResources().getDrawable(resID));
//设置每一页spec显示的view
tabSpec.setIndicator(tabView);
tabHost.addTab(tabSpec);
tabInfo = new TabInfo("Tab" + i, HoroscopeFragment.class, args);
tabInfo.On = (ImageView) tabView.findViewById(R.id.on);
tabInfo.Off = (ImageView) tabView.findViewById(R.id.off);
tabInfo.Tab = tabView;
this.mapTabInfo.put(tabInfo.tag, tabInfo);
//默认第一张显示的标签页
this.onTabChanged("Tab0");
tabHost.setOnTabChangedListener(this);
}
}
@Override
public void onTabChanged(String tabId) {
TabInfo newTab = this.mapTabInfo.get(tabId);
for (Map.Entry<String, TabInfo> t : mapTabInfo.entrySet()) {
if (t.getKey().equals(tabId)) {
t.getValue().On.setVisibility(View.VISIBLE);
t.getValue().Off.setVisibility(View.INVISIBLE);
} else {
t.getValue().On.setVisibility(View.INVISIBLE);
t.getValue().Off.setVisibility(View.VISIBLE);
}
}
hScrollView.requestChildRectangleOnScreen(newTab.Tab, new Rect(0, 0, newTab.Tab.getWidth(), 1), false);
int pos = this.tabHost.getCurrentTab();
this.viewPager.setCurrentItem(pos, true);
}
public class PagerAdapter extends FragmentPagerAdapter {
private List<android.support.v4.app.Fragment> fragments;
public PagerAdapter(android.support.v4.app.FragmentManager fm, List<android.support.v4.app.Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public android.support.v4.app.Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
}
HoroscaopeFragment.java
public class HoroscopeFragment extends Fragment {
/**
*
* @param inflater 布局
* @param container 容器
* @param savedInstanceState
* @return view
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//i是Key后面的数字,实例化fragment后返回的参数
int i = getArguments().getInt("i") + 1;
//设置View的布局
final View view = inflater.inflate(R.layout.fragment_main,container,false);
/**
* 该方法用以异步获取在服务器配置的文字项内容,并设置为textView的文本,
* 如获取失败,textView的文本会设置为defaultValue。
* 详情见http://www.duducat.com/?article-doc.html
*/
ActiveConfig.setTextViewWithKey("Key"+i,null,(TextView)view.findViewById(R.id.content));
ActiveConfig.setImageViewWithKey("Key" + i,null,(ImageView)view.findViewById(R.id.cover));
ActiveConfig.getImageAsync("Key" + i,new ActiveConfig.AsyncGetImageHandler() {
/**
* 异步获取图片,成功设置显示
* @param drawable
*/
@Override
public void OnSuccess(Drawable drawable) {
((ImageView) view.findViewById(R.id.cover)).setImageDrawable(drawable);
view.findViewById(R.id.loading).setVisibility(View.INVISIBLE);
}
@Override
public void OnFailed() {
}
});
view.findViewById(R.id.content).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
ActiveConfig.clearCache();
return true;
}
});
return view;
}
}
ResizableImageView.java
public class ResizableImageView extends ImageView {
public ResizableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* onMeasure来设置我们的视图的大小,但还有一个疑惑的地方,
* EXACTLY,AT_MOST,UNSPECIFIED和layout_是如何对应的呢?什么情况下对应什么值呢?
* MATCH_PARENT对应于EXACTLY,WRAP_CONTENT对应于AT_MOST,
* 其他情况也对应于EXACTLY,它和MATCH_PARENT的区别在于size值不一样。
*
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable d = getDrawable();
if(d != null){
// MeasureSpec.getSize(widthMeasureSpec):根据提供的测量值(格式)提取大小值(这个大小也就是我们通常所说的大小)
int width = MeasureSpec.getSize(widthMeasureSpec);
//Math.ceil() 得到不小于他的最小整数
//获取Drawable d 对象的大小d.getIntrinsicHeight(),d.getIntrinsicWidth()
int height = (int)Math.ceil((float) width * (float)d.getIntrinsicHeight() / d.getIntrinsicWidth());
//设置自定义View的大小。详细描述见:http://blog.csdn.net/pi9nc/article/details/18764863
setMeasuredDimension(width,height);
}
else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
activtiy_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <!-- android:fillViewport=\"true\" 什么意思
ScrollView里只放一个元素.
当ScrollView里的元素想填满ScrollView时,使用"fill_parent"是不管用的,必需为ScrollView设置:
android:fillViewport="true".
当ScrollView没有fillVeewport=“true”时,里面的元素(比如LinearLayout)会按照wrap_content来计算
(不论它是否设了"fill_parent"),而如果LinearLayout的元素设置了fill_parent,那么也是不管用的,
因为LinearLayout依赖里面的元素,而里面的元素又依赖LinearLayout,这样自相矛盾.
所以里面元素设置了fill_parent,也会当做wrap_content来计算.
-->
<HorizontalScrollView
android:id="@+id/hScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/header_bg"
android:fillViewport="true"> <!-- android:tabStripEnabled="false" 不在选项卡绘制-->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:tabStripEnabled="false"> </TabWidget> </HorizontalScrollView> <FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</TabHost> </LinearLayout>
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/content_bg"> <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.jingling.practice.horoscope.ResizableImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:visibility="visible"/>
<ProgressBar
android:id="@+id/loading"
style="?android:attr/progressBarStyleLarge"
android:layout_width="100dp"
android:layout_height="150dp"
android:layout_gravity="center"
android:indeterminate="true"
android:paddingTop="50dp" />
</FrameLayout> <ScrollView
android:id="@+id/scrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="20dp" > <TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="1.5"
android:singleLine="false"
android:textColor="#ffffffff" />
</ScrollView>
</LinearLayout>
tab_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="matrix"
android:src="@drawable/a10_0"
android:visibility="invisible" /> <ImageView
android:id="@+id/off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="matrix"
android:src="@drawable/a10_1"
android:visibility="visible" /> </FrameLayout>
源码已经上传至:https://github.com/presCheng/horoscope
星座物语APP的更多相关文章
- UESTC_秋实大哥の恋爱物语 2015 UESTC Training for Search Algorithm & String<Problem K>
K - 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others) Memory Limit: 32000/32000KB (Java/Others) Su ...
- 怪奇物语第二季/全集Stranger Things迅雷下载
Netflix的叫好叫座剧<怪奇物语 Stranger Things>第二季更新上线日期为美国时间10月27日,第二季讲述在1984年(相隔上季一年),印第安纳州的Hawkins镇市民仍然 ...
- 2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp
秋实大哥の恋爱物语 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 De ...
- cdoj1091-秋实大哥の恋爱物语 【kmp】
http://acm.uestc.edu.cn/#/problem/show/1091 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others) Memo ...
- FZU 2234 牧场物语【多线程dp】
Problem 2234 牧场物语 Problem Description 小茗同学正在玩牧场物语.该游戏的地图可看成一个边长为n的正方形. 小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方 ...
- 得物(毒)APP,8位抽奖码需求,这不就是产品给我留的数学作业!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- FZU2234 牧场物语 DP
题意:先去再回,不能吃重复的,获取最大值 分析:等价于两个人同时去,不能吃重复的 定义dp[i][j][k]表示从起点走k步,第一个人的横坐标是i,第二个人的横坐标是j的最最大值 这个题和bc上一个回 ...
- 一步一步搞懂支持向量机——从牧场物语到SVM(上)
之前在数据挖掘课程上写了篇关于SVM的"科普文",尽量通俗地介绍了SVM的原理和对各公式的理解.最近给正在初学机器学习的小白室友看了一遍,他觉得"很好,看得很舒服&quo ...
- NOIP2016——大家一起实现の物语
由于最近硬盘挂了,换了个固态硬盘,比赛结束后四天一直在装Linux,所以最近一直没怎么更新 看起来挺漂亮的 比赛前一个月申请停了一个月晚自习,在我们这座城市里能做到这种事情已经可以被称为奇迹了,并且在 ...
随机推荐
- window.location.href问题,点击,跳转到首页
onClick="window.location.href='./';" 点击,跳转到首页. location.href=url Js中实现跳转 window.location.h ...
- Apache下PHP的几种工作方式
PHP在Apache中一共有三种工作方式:CGI模式.Apache模块DLL.FastCGI模式. 一.CGI模式 PHP 在 Apache 2中的 CGI模式.编辑Apache 配置文件httpd. ...
- C++ STL基本容器的使用
C++中有两种类型的容器:顺序容器和关联容器.顺序容器主要有vector.list.deque等.其中vector表示一段连续的内存,基于数组实现,list表示非连续的内存,基于链表实现,deque与 ...
- Sqlserver 正则替换函数的一种实现
--函数 IF OBJECT_ID(N'dbo.RegexReplace') IS NOT NULL DROP FUNCTION dbo.RegexReplace GO CREATE FUNCTION ...
- DIV+CSS两种盒子模型
盒子模型有两种,分别是 IE 盒子模型和标准 W3C 盒子模型.他们对盒子模型的解释各不相同, 先来看看我们熟悉的标准盒子模型: 从上图可以看到标准 W3C 盒子模型的范围包括 margin.bord ...
- UE标签排列方式
UE是一款很顺手的文件编辑软件.打开文本,都会有个标签.根据个人喜好,我喜欢标签都展开,方便快速选取指定文本. 设置如下: 高级>配置>应用程序布局>可停靠窗口>类型 ...
- 转:PHP 使用ZipArchive压缩文件并下载
原文来自于:http://courages.us/archives/176 网站上需要提供一些打印数据给用户下载,这些文件每次都需要重新生成,因为随时都会有新的数据产生.网络上关于PHP的压缩功能实现 ...
- [Android] AudioTrack::start
AudioTrack的start方法用于实现Android的音频输出,start究竟做了什么?回顾一下上一小节createTrack_l的最后部分,通过binder返回了一个Track的句柄,并以被保 ...
- haskell 开发环境配置
haskell是一门通用函数式语言,几乎可以进行任何种类的开发,包括命令行,GUI,数据库,Web.源代码可以跨平台: Linux,Mac, Windows, FreeBSD 等. haskell特点 ...
- 14.4.3 Adaptive Hash Index 自适应hash index
14.4.3 Adaptive Hash Index 自适应hash index 自适应hash index(AHI) 让InnoDB 执行更像内存数据库在系统使用合适的负载组合和足够的内存用于Buf ...