摘要:無論是跑馬燈新聞標(biāo)題還是餓了么的導(dǎo)航欄,它們的作用都是一樣的,那就是復(fù)用有限的屏幕空間,展示更為豐富的內(nèi)容。最后附上源碼的地址參考文章之的簡(jiǎn)單使用仿淘寶首頁的淘寶頭條垂直滾動(dòng)仿餓了么首頁導(dǎo)航欄
在淘寶App的首頁中間位置,有一塊小小的地方在不知疲倦地循壞滾動(dòng)著頭條標(biāo)題(見下圖的紅框區(qū)域),這樣的設(shè)計(jì)無疑能夠在有限的手機(jī)屏幕上展示更豐富的內(nèi)容。而實(shí)現(xiàn)這一功能需要用到的控件就是我在上一篇文章中提到的ViewFlipper控件(詳見“參考文章”)。在網(wǎng)上看到一篇博客是用自定義ViewFlipper實(shí)現(xiàn)的,但我卻想起了我在實(shí)現(xiàn)餓了么導(dǎo)航欄時(shí)的思路:既然ViewFlipper的每個(gè)視圖最多只有兩個(gè)新聞標(biāo)題,那我們可以先將標(biāo)題兩兩分組(奇數(shù)的話最后一個(gè)多帶帶為一組),每組創(chuàng)建一個(gè)視圖,這樣就計(jì)算出了需要?jiǎng)?chuàng)建多少個(gè)視圖,然后再在每個(gè)視圖中加載數(shù)據(jù)就可以了。這樣的話,直接用原生的ViewFlipper就可以做到了。
1、創(chuàng)建工程及布局創(chuàng)建一個(gè)MarqueeNewsActivity,其布局文件如下
activity_marquee_news.xml
再創(chuàng)建ViewFlipper的視圖布局,也就是新聞標(biāo)題的布局。一共兩個(gè)線性布局,每個(gè)放置一個(gè)新聞標(biāo)題。由于第二個(gè)可能需要消失,所以設(shè)置ID。
title_view.xml
標(biāo)簽的背景就是一個(gè)紅色的邊框,也很簡(jiǎn)單:
編寫完布局之后,下面就來編寫代碼了。
2、Activity代碼代碼都是按照前面說到的思路寫的,我在必要的地方也加了注釋,相信大家讀起來不難理解。要注意的是新聞標(biāo)題數(shù)目可能是奇數(shù),這樣最后一個(gè)視圖就只有一個(gè)標(biāo)題。為了美觀,我們需要讓第二個(gè)線性布局消失掉,所以要加一個(gè)判斷條件。ViewFlipper的視圖進(jìn)入和退出是通過動(dòng)畫來設(shè)置的,大家也可以根據(jù)需要增加我們需要的動(dòng)畫效果。
MarqueeNewsActivity
public class MarqueeNewsActivity extends AppCompatActivity { private Context context; private ViewFlipper viewFlipper; private Listtitles; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper); initData(); setViews(); } /** * 初始化新聞標(biāo)題數(shù)據(jù) */ private void initData() { titles = new ArrayList(); titles.add("日本老年犯罪嚴(yán)重,監(jiān)獄成老人無奈歸宿"); titles.add("美機(jī)闖香港空域"); titles.add("大學(xué)教授亮工資條"); titles.add("英國(guó)空軍轟炸IS"); titles.add("三連敗收官!柯潔再負(fù)AlphaGo,人機(jī)大戰(zhàn)遭零封"); titles.add("女子爬山遭雷劈暈"); titles.add("電信詐騙現(xiàn)新騙局"); } /** * 為每一頁設(shè)置視圖 */ private void setViews() { if (titles.size() > 0) { //計(jì)算ViewFlipper視圖的數(shù)目 int viewNum = titles.size() / 2 + 1; for (int i = 0; i < viewNum; i++) { //每一個(gè)視圖的第一個(gè)新聞標(biāo)題中集合中的下標(biāo)值 final int position = i * 2; View itemView = View.inflate(context, R.layout.item_view, null); TextView tvTitle1 = (TextView) itemView.findViewById(R.id.tv_title1); TextView tvTitle2 = (TextView) itemView.findViewById(R.id.tv_title2); LinearLayout ll = (LinearLayout) itemView.findViewById(R.id.ll_second); tvTitle1.setText(titles.get(position)); //判斷第二行是否有數(shù)據(jù) if (position + 1 < titles.size()) { tvTitle2.setText(titles.get(position + 1)); } else { //表示該視圖的第二個(gè)標(biāo)題沒有數(shù)據(jù),隱藏第二行布局 ll.setVisibility(View.GONE); } //標(biāo)題1的點(diǎn)擊事件 tvTitle1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, titles.get(position), Toast.LENGTH_SHORT).show(); } }); //標(biāo)題2的點(diǎn)擊事件 tvTitle2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, titles.get(position + 1), Toast.LENGTH_SHORT).show(); } }); viewFlipper.addView(itemView); } //視圖進(jìn)入動(dòng)畫 viewFlipper.setInAnimation(context, R.anim.news_in); //視圖退出動(dòng)畫 viewFlipper.setOutAnimation(context, R.anim.news_out); //自動(dòng)開始滾動(dòng) viewFlipper.setAutoStart(true); //視圖的切換間隔 viewFlipper.setFlipInterval(3000); // viewFlipper.startFlipping(); } } }
順便放一下動(dòng)畫文件吧。
new_in.xml
new_out.xml的代碼類似,只需要將fromYDelta的值改為0,toYDelta的值改為-100%p就可以了。
效果如下:
都說編程最重要的是思想,現(xiàn)在就來抽取和總結(jié)一下我學(xué)習(xí)到的思想,盡管看起來還是很稚嫩,但畢竟也是我前進(jìn)路上的一個(gè)腳印。
無論是跑馬燈新聞標(biāo)題還是餓了么的導(dǎo)航欄,它們的作用都是一樣的,那就是“復(fù)用”有限的屏幕空間,展示更為豐富的內(nèi)容。它們有著以下的共同點(diǎn):
將一定數(shù)量的數(shù)據(jù)分配在多個(gè)視圖(View)中展示;
每個(gè)數(shù)據(jù)的類型都是一樣的,比如餓了么導(dǎo)航欄中的每個(gè)數(shù)據(jù)單元就是一張圖片和幾個(gè)文字;
每一個(gè)視圖的內(nèi)容雖然不一樣,但每一個(gè)視圖的布局都是一樣的(消失或者隱藏的子布局也算在內(nèi));
每一個(gè)視圖內(nèi)的最小數(shù)據(jù)單元(item)的布局也是一樣的。
打個(gè)比方,就好像我們?cè)谛偶埳蠈懽魑囊粯?,每一頁的方格?shù)目都是固定的,方格的大小也是一樣的,當(dāng)一頁的方格用完后,就另起一頁再寫。其實(shí)這也有點(diǎn)像ListView的分頁加載,可以將每一個(gè)視圖都當(dāng)成一頁,一頁放不下就一頁一頁地加載。這里實(shí)際上是復(fù)用了View的布局和item的布局了。
思想指導(dǎo)行動(dòng),遇到符合上面特征的數(shù)據(jù)時(shí),我們就可以用分頁的思想按照下面的步驟一步步來:
編寫頁面視圖(View)的布局和數(shù)據(jù)單元(item)的布局;
計(jì)算item的個(gè)數(shù);
確定每一個(gè)View中的item數(shù)目,對(duì)item進(jìn)行分組
根據(jù)View中的item數(shù)目計(jì)算需要的View數(shù)目;
創(chuàng)建每一個(gè)View(一般使用for循環(huán));
將數(shù)據(jù)填充至每一個(gè)item中
考慮item數(shù)目(比如單數(shù)與奇數(shù))對(duì)View布局的影響。
大體的步驟就是這樣了,實(shí)際運(yùn)用中可能會(huì)稍有不同,不必太過拘泥,只要有這種思想就可以了。
4、后記文章到這里就寫完了,這點(diǎn)小小的總結(jié)希望能對(duì)大家有點(diǎn)幫助,也希望能拋磚引玉。最后補(bǔ)充一點(diǎn),如果你需要在項(xiàng)目中多次用到這種效果的話,那么可以看看我在參考文章一節(jié)中列出的博客,使用自定義控件的方法來寫,如果就一兩處用到,那么用原生的ViewFlipper就足夠了。
最后附上源碼的GitHub地址:
ViewFlipperDemo
Android之ViewFlipper的簡(jiǎn)單使用
仿淘寶首頁的淘寶頭條View垂直滾動(dòng)
仿餓了么首頁導(dǎo)航欄(ViewPager)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67143.html
摘要:基于仿照今日頭條的移動(dòng)端項(xiàng)目源碼地址預(yù)覽地址前言先占個(gè)坑位。項(xiàng)目中還有許多可以完善的地方,不足之處希望小伙伴們可以,我會(huì)在這里更新。目前還沒有全面地測(cè)試該項(xiàng)目,有問題提問,大家一起學(xué)習(xí)。 toutiao 基于Vue2.0仿照今日頭條的移動(dòng)端項(xiàng)目 源碼地址:toutiao_Vue2.0 預(yù)覽地址:toutiao_Vue2.0 前言 先占個(gè)坑位。 之前打算做個(gè)東西熟悉vue的使用,由于...
閱讀 1141·2021-09-22 16:04
閱讀 1519·2019-08-30 15:43
閱讀 1135·2019-08-29 14:01
閱讀 3465·2019-08-26 12:19
閱讀 3381·2019-08-26 12:15
閱讀 1471·2019-08-26 12:13
閱讀 3294·2019-08-23 17:00
閱讀 1513·2019-08-23 15:38