一、背景
中华万年历下拉后加载今天的图片,只能从左向右滑动查看最近7天的图片动态,向左提示“明天还没到”。
毒蛇电影App点击左上角日期后,弹出图片中可以下载和分享。
我们项目中结合这两个功能,实现一个称为“日签”的功能。
该功能核心要点:
1、使用viewpager实现翻页动态缩放的效果,类似几年前Galley的动态效果
2、一般我们viewpager用在轮播图片,在首次安装轮播图片中更常见,那个viewpager的item仅仅是一张图片而已,而这个功能中的item中还有其他元素,我称之为复杂的Layout。由于viewpager的Adapter与listview的Adapter不同,具体怎么不同,自行查看
3、一般viewpager加载后直接向左滑动多张图片,而这个功能中由于日期一般都是左小右大,首次加载后显示当天,只能查看往日的,所以需要向右滑动多张图片
二、实战
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;
/**
* 创建日期: 2017/10/16 on 下午10:01
* 描述:
* 作者: Jason [email protected]
*/
public class DaySignActivity extends AppCompatActivity {
private ViewPager mViewPager;
private LinearLayout mLayout;
private List beanList = new ArrayList<>();
private ArrayList 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);
}
});
// 实现Viewpager的翻页动态缩放的效果
mViewPager.setPageTransformer(true, new GallyPageTransformer());
}
private void initData() {
mpViews = new ArrayList();
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,参考实现了阿呆哥哥的viewpager实现画廊效果GallyPageTransformer。
(http://www.cnblogs.com/wjtaigwh/p/5982068.html)
//实现Viewpager的翻页动态缩放的效果
mViewPager.setPageTransformer(true, new GallyPageTransformer());
不过这个这个不是本篇的重点,这个在鸿洋大神的博客几年前就有踪影(http://my.csdn.net/lmj623565791)
2、重点是viewpager中的item是复杂的一个Layout,这个困惑了我一段时间,后来发挥了自己创造力,突破啦。哈哈哈,可能自己太菜了,这个在网上一直没找到现成的一个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;
/**
* 创建日期: 2017/10/16 on 下午10:30
* 描述:
* 作者: Jason [email protected]
*/
public class MyVPAdapter extends PagerAdapter {
private List mData;
private Context mContext;
private ArrayList mList;
private ImageView daysignIv;
public MyVPAdapter(Context mContext, ArrayList mList, List mData) {
this.mContext = mContext;
this.mList = mList;
this.mData = mData;
}
@Override
public int getCount() {
// 获取要滑动的控件的数量
return this.mList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
// 来判断显示的是否是同一张图片,这里我们将两个参数相比较返回即可
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();
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的构造器传过去,并且把实体数据传过去,Adapter中加载图片需要使用。
3、一般viewpager加载后手指从右向左滑动多张图片,而这里日期左小右大,首次加载后显示当天,只能查看往日的,所以需要从左向右滑动多张图片。
后台添加图片时都是过几天加一次,日期大的排在最前面,所以这里实现的向右滑动,也是把数据进行了处理实现的。之前一直没思路,而且网上也没找到类似这种加载后直接向右滑动的文章。
这里我模拟了一些假数据
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的对应,相当于我们把数据和position做了处理。