星座物语APP

效果图:

    星座物语APP

这里的后台管理用的是duducat,大家可以去百度看说明。图片,文字都在duducat后台服务器上,可以自己修改的。(PS:图片这里是随便找的)

http://www.duducat.com/

我就直接上代码了,如果有不懂的可以联系我。

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

上一篇:MFC加载皮肤 转自:http://www.cctry.com/thread-4032-1-1.html


下一篇:SOA服务设计与实现的几个语言无关的原则速记