一、背景


中華萬年歷下拉后加載今天的圖片,只能從左向右滑動查看最近7天的圖片動態(tài),向左提示“明天還沒到”。
毒蛇電影App點擊左上角日期后,彈出圖片中可以下載和分享。
我們項目中結合這兩個功能,實現(xiàn)一個稱為“日簽”的功能。
該功能核心要點:
1、使用viewpager實現(xiàn)翻頁動態(tài)縮放的效果,類似幾年前Galley的動態(tài)效果
2、一般我們viewpager用在輪播圖片,在首次安裝輪播圖片中更常見,那個viewpager的item僅僅是一張圖片而已,而這個功能中的item中還有其他元素,我稱之為復雜的Layout。由于viewpager的Adapter與listview的Adapter不同,具體怎么不同,自行查看
3、一般viewpager加載后直接向左滑動多張圖片,而這個功能中由于日期一般都是左小右大,首次加載后顯示當天,只能查看往日的,所以需要向右滑動多張圖片

二、實戰(zhàn)
package com.jason.dailyproject.daysign;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.jason.dailyproject.R;
import java.util.ArrayList;
import java.util.List;
/**
* 創(chuàng)建日期: 2017/10/16 on 下午10:01
* 描述:
* 作者: Jason jianbo311@163.com
*/
public class DaySignActivity extends AppCompatActivity {
private ViewPager mViewPager;
private LinearLayout mLayout;
private List<DaySignImgBean> beanList = new ArrayList<>();
private ArrayList<View> mpViews;
private MyVPAdapter mAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_day_sign);
mViewPager = (ViewPager) findViewById(R.id.viewPager);
mLayout = (LinearLayout) findViewById(R.id.daysign_layout);
//初始化
initData();
mViewPager.setOffscreenPageLimit(3);
int pagerWidth = (int) (getResources().getDisplayMetrics().widthPixels * 3.5f / 5.0f);
ViewGroup.LayoutParams lp = mViewPager.getLayoutParams();
if (lp == null) {
lp = new ViewGroup.LayoutParams(pagerWidth, ViewGroup.LayoutParams.MATCH_PARENT);
} else {
lp.width = pagerWidth;
}
mViewPager.setLayoutParams(lp);
mLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mViewPager.dispatchTouchEvent(motionEvent);
}
});
// 實現(xiàn)Viewpager的翻頁動態(tài)縮放的效果
mViewPager.setPageTransformer(true, new GallyPageTransformer());
}
private void initData() {
mpViews = new ArrayList<View>();
String imgUrl1 = "https://qiniu.image.cq-wnl.com/sentenceimg/";
String imgUrl2 = ".jpg?imageView2/1/w/1160/h/1406/q/90";
String detailsUrl1 = "http://www.51wnl.com/products.html?f=13&date=";
String detailsUrl2 = "&p=i&index=0";
beanList.add(new DaySignImgBean(imgUrl1 + "2017101742e884e46c3a48f0a82e8b2591abb799" + imgUrl2, "2017-10-17", "http://dwz.cn/6FxTWY"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101694022dd4f0224ce0ac066223220b2148" + imgUrl2, "2017-10-16", "http://dwz.cn/6FxVF8"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101586b86a08342a47f7add1c3ecbccd9fd3" + imgUrl2, "2017-10-15", "http://dwz.cn/6FxXv7"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101432d29ad49e9849e59a24073270550981" + imgUrl2, "2017-10-14", "http://dwz.cn/6FyL6I"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171013c5d4c55751a94da68100a79029a5938f" + imgUrl2, "2017-10-13", "http://dwz.cn/6FyM5f"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171012f9942156a7544ff898cedac622939801" + imgUrl2, "2017-10-12", "http://dwz.cn/6FyN0z"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171011640e9be5099e4d2ba75dc38cda51c720" + imgUrl2, "2017-10-11", "http://dwz.cn/6FyO3I"));
for (int i = 0; i < beanList.size(); i++) {
View v = LayoutInflater.from(this).inflate(R.layout.item_daysign_vp, null);
mpViews.add(v);
}
mAdapter = new MyVPAdapter(this, mpViews, beanList);
mViewPager.setAdapter(mAdapter);
final int currentPosition = beanList.size() - 1;
mViewPager.setCurrentItem(currentPosition);
addEvent(0);
mAdapter.notifyDataSetChanged();
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
addEvent(currentPosition - position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void addEvent(final int position) {
final DaySignImgBean imgBean = beanList.get(position);
View view = mpViews.get(position);
FrameLayout itemLayout = (FrameLayout) view.findViewById(R.id.daysign_item_layout);
Button shareBtn = (Button) view.findViewById(R.id.daysign_share_btn);
Button downloadBtn = (Button) view.findViewById(R.id.daysign_download_btn);
ImageView daysignIv = (ImageView) view.findViewById(R.id.daysign_iv);
itemLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//圖片詳情
if (TextUtils.isEmpty(imgBean.getDetailsUrl())) {
return;
}
Intent intent = new Intent(DaySignActivity.this, WebViewActivity.class);
intent.putExtra("url", imgBean.getDetailsUrl());
startActivity(intent);
}
});
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//下載圖片
Toast.makeText(DaySignActivity.this, "下載" + imgBean.getShowDate() + "圖片",
Toast.LENGTH_LONG).show();
}
});
shareBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//分享圖片
Toast.makeText(DaySignActivity.this, "分享" + imgBean.getShowDate() + "圖片",
Toast.LENGTH_LONG).show();
}
});
}
}
1、主頁中就1個viewpager,參考實現(xiàn)了阿呆哥哥的viewpager實現(xiàn)畫廊效果GallyPageTransformer。
(http://www.cnblogs.com/wjtaigwh/p/5982068.html)
//實現(xiàn)Viewpager的翻頁動態(tài)縮放的效果
mViewPager.setPageTransformer(true, new GallyPageTransformer());
不過這個這個不是本篇的重點,這個在鴻洋大神的博客幾年前就有蹤影(http://my.csdn.net/lmj623565791)
2、重點是viewpager中的item是復雜的一個Layout,這個困惑了我一段時間,后來發(fā)揮了自己創(chuàng)造力,突破啦。哈哈哈,可能自己太菜了,這個在網(wǎng)上一直沒找到現(xiàn)成的一個demo。
package com.jason.dailyproject.daysign;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.jason.dailyproject.R;
import java.util.ArrayList;
import java.util.List;
/**
* 創(chuàng)建日期: 2017/10/16 on 下午10:30
* 描述:
* 作者: Jason jianbo311@163.com
*/
public class MyVPAdapter extends PagerAdapter {
private List<DaySignImgBean> mData;
private Context mContext;
private ArrayList<View> mList;
private ImageView daysignIv;
public MyVPAdapter(Context mContext, ArrayList<View> mList, List<DaySignImgBean> mData) {
this.mContext = mContext;
this.mList = mList;
this.mData = mData;
}
@Override
public int getCount() {
// 獲取要滑動的控件的數(shù)量
return this.mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
// 來判斷顯示的是否是同一張圖片,這里我們將兩個參數(shù)相比較返回即可
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
int currentPosition = mList.size() - 1;
View view = mList.get(currentPosition - position);
daysignIv = (ImageView) view.findViewById(R.id.daysign_iv);
setData(currentPosition - position);
// 當要顯示的圖片可以進行緩存的時候,會調用這個方法進行顯示圖片的初始化,
// 我們將要顯示的ImageView加入到ViewGroup中,然后作為返回值返回即可
container.addView(view);
return this.mList.get(currentPosition - position);
}
private void setData(int position) {
Glide.with(mContext).load(mData.get(position).getImgUrl())
.centerCrop()
.dontAnimate()
.thumbnail(0.5f)
.placeholder(R.mipmap.b)
.error(R.mipmap.b)
.into(daysignIv);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mList.get(mList.size() - 1 - position));
}
}
一般我們的viewpager用在輪播圖片中比較多,最常見的就是首次安裝后輪播版本主要功能,viewpager的item就是一張張圖片而已,而這個功能中viewpager的item的圖片是中有其他元素,可以下載,可以分享,還可以設計其他的事件。我又并不想設計成一個個fragment,所以有了這個問題。
核心代碼
mpViews = new ArrayList<View>();
for (int i = 0; i < beanList.size(); i++) {
View v = LayoutInflater.from(this).inflate(R.layout.item_daysign_vp, null);
mpViews.add(v);
}
mAdapter = new MyVPAdapter(this, mpViews, beanList);
在activity中new出來一個個View,通過Adapter的構造器傳過去,并且把實體數(shù)據(jù)傳過去,Adapter中加載圖片需要使用。
3、一般viewpager加載后手指從右向左滑動多張圖片,而這里日期左小右大,首次加載后顯示當天,只能查看往日的,所以需要從左向右滑動多張圖片。
后臺添加圖片時都是過幾天加一次,日期大的排在最前面,所以這里實現(xiàn)的向右滑動,也是把數(shù)據(jù)進行了處理實現(xiàn)的。之前一直沒思路,而且網(wǎng)上也沒找到類似這種加載后直接向右滑動的文章。
這里我模擬了一些假數(shù)據(jù)
String imgUrl1 = "https://qiniu.image.cq-wnl.com/sentenceimg/";
String imgUrl2 = ".jpg?imageView2/1/w/1160/h/1406/q/90";
beanList.add(new DaySignImgBean(imgUrl1 + "2017101742e884e46c3a48f0a82e8b2591abb799" + imgUrl2, "2017-10-17", "http://dwz.cn/6FxTWY"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101694022dd4f0224ce0ac066223220b2148" + imgUrl2, "2017-10-16", "http://dwz.cn/6FxVF8"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101586b86a08342a47f7add1c3ecbccd9fd3" + imgUrl2, "2017-10-15", "http://dwz.cn/6FxXv7"));
beanList.add(new DaySignImgBean(imgUrl1 + "2017101432d29ad49e9849e59a24073270550981" + imgUrl2, "2017-10-14", "http://dwz.cn/6FyL6I"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171013c5d4c55751a94da68100a79029a5938f" + imgUrl2, "2017-10-13", "http://dwz.cn/6FyM5f"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171012f9942156a7544ff898cedac622939801" + imgUrl2, "2017-10-12", "http://dwz.cn/6FyN0z"));
beanList.add(new DaySignImgBean(imgUrl1 + "20171011640e9be5099e4d2ba75dc38cda51c720" + imgUrl2, "2017-10-11", "http://dwz.cn/6FyO3I"));

后來看了判斷viewpager左右滑動方向的文章后,有點思路
了。對position做文章?。。?!
http://www.cnblogs.com/lovelyYakir/p/6156137.html
activity中
final int currentPosition = beanList.size() - 1;
mViewPager.setCurrentItem(currentPosition);
addEvent(0);
mAdapter.notifyDataSetChanged();
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
addEvent(currentPosition - position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Adapter中
@Override
public Object instantiateItem(ViewGroup container, int position) {
int currentPosition = mList.size() - 1;
View view = mList.get(currentPosition - position);
daysignIv = (ImageView) view.findViewById(R.id.daysign_iv);
setData(currentPosition - position);
// 當要顯示的圖片可以進行緩存的時候,會調用這個方法進行顯示圖片的初始化,
// 我們將要顯示的ImageView加入到ViewGroup中,然后作為返回值返回即可
container.addView(view);
return this.mList.get(currentPosition - position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mList.get(mList.size() - 1 - position));
}
保證兩邊的position的對應,相當于我們把數(shù)據(jù)和position做了處理。