动用kotlin写一个仿微信点击图片浏览的功力

图片 1

weibo_info

用了一些新控件,仿的微博界面
主要有向上滑动图片渐变消失,tablayout使用,用recyclerview解决1-9张图片的显示问题,点击图片后进入viewpager进行缩放,保存等操作。
layout: photo

1.使用overridePendingTransition方法实现Activity跳转动画overridePendingTransition方法是Activity中提供的Activity跳转动画方法,通过该方法可以实现Activity跳转时的动画效果,简单例子如下:

大概就是这么个效果,图片从小到大的一个效果,然后滑动切换图片,点击后会返回对应图片的位置,其实比较容易,用到的是ActivityOptions,一个activity的转场动画,下面说一下怎么实现。

效果图:

2015-12-11-121720.png

2015-12-11-121824.png

2015-12-11-121900.png

Intent intent =newIntent(MainActivity.this, SecondActivity.class);startActivity;overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left);

github地址点这里

应用:

设置向上滚动消失的view

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<!-- 设置图片-->
<!--添加一个定义了app:layout_collapseMode="parallax" 属性的ImageView,出现和消失会有过度-->
<ImageView
android:id="@+id/backdrop"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/qingdao"
app:layout_collapseMode="parallax"
/>

Toolbar自定义menu:
//actionbar导入menu中的设置栏
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar_actions, menu);
return super.onCreateOptionsMenu(menu);
}


TabLayout配合viewpager使用配置标题
<!-- 自定义tab-->
    <!-- 设置可滑动-->
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

    <android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
//设置ViewPager
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);
//设置tablayout,viewpager上的标题
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.colorPrimaryDark));
}
/**
 * 设置item
 * @param viewPager
*/
private void setupViewPager(ViewPager viewPager) {
    InfoAdapter adapter = new InfoAdapter(getSupportFragmentManager());
    adapter.addFragment(new HomeFragment(), "主页");
    adapter.addFragment(new WeiBoFragment(), "微博");
    adapter.addFragment(new PhotoFragment(), "相册");
    viewPager.setAdapter(adapter);
}
/**
 * Created by chenlijin on 2015/12/10. 传入标题的FragmentPagerAdapter
 */
public class InfoAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();

public InfoAdapter(FragmentManager fm) {
super(fm);
    }

public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);

    }

@Override
public Fragment getItem(int position) {
return mFragments.get(position);
    }

@Override
public int getCount() {
return mFragments.size();
    }

@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
    }
}

Glide加载图片:

public static void loadToImageView(String url, ImageView imageView) {
if (url.endsWith("gif")) {
loadToImageViewStaticGif(url, imageView);
    } else {
        Glide.with(BaseApplication.getContext())
                .load(url)
                .placeholder(R.drawable.loading)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .centerCrop()
                .into(imageView);
    }
}

Glide下载图片:

public static void saveImage(String url, final String name) {
    Glide.with(BaseApplication.getContext())
            .load(url)
            .asBitmap()
            .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
            .into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
// Do something with bitmap here.
saveBitmap(name,resource);
                }

            });
}

public static void saveBitmap(String bitName, Bitmap mBitmap) {
    File f = new File("/sdcard/Pictures/" + bitName+".png");
try {
        f.createNewFile();
    } catch (IOException e) {

    }
    FileOutputStream fOut = null;
try {
        fOut = new FileOutputStream(f);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
try {
        fOut.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
try {
        fOut.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1~9张图片的加载:
使用recyclerview加载三种不同的布局。

@Override
public int getItemViewType(int position) {
switch (mShopInfoList.get(position).getImageList().size()) {
case 1:
return PIC_ONE;
case 4:
return PIC_FOUR;
default:
return PIC_OTHER;
    }
}

share动画:
1,设置共享元素的标签
android:transitionName=”share”
2,通过ActivityOptions,传入要分享的view和标签名
Intent intent = new Intent(mLayoutInflater.getContext(),
OnePicZoomInImageActivity.class);
intent.putParcelableArrayListExtra(Config.IMAGE_URL_LIS T,
(ArrayList<? extends Parcelable>) imageList);
// of both activities are defined with android:transitionName=”share”
ActivityOptions options = ActivityOptions
.makeSceneTransitionAnimation((Activity) mLayoutInflater.getContext(),
imageview, “share”);
mLayoutInflater.getContext().startActivity(intent,options.toBundle());
普通activity的切换动画:
mLayoutInflater.getContext().startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation((Activity)mLayoutInflater.getContext()).toBundle());
设置statusbar为透明色
//设置statusbar为透明色
private void setStatusBarColor() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
window.setNavigationBarColor(Color.TRANSPARENT);
}
给imageview添加手势操作
PhotoViewAttachermAttacher;
mAttacher = new PhotoViewAttacher(mImageView);

注意:overridePendingTransition在startActivity或者是finish方法立刻执行才有效

关于kotlin的配置就不过多说了,网上好多教程(最近kotlin好火)

遇到的问题:

viewpager和photoview一起使用崩溃的问题
java.lang.IllegalArgumentException: pointerIndexoutofrange

public class PictureChildViewPager extends ViewPager {
public PictureChildViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}

public PictureChildViewPager(Context context) {
super(context);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
}
}

@Override
public boolean onTouchEvent(MotionEvent arg0) {
try {
return super.onTouchEvent(arg0);
} catch (IllegalArgumentException ex) {
return false;
}
}

scrollview下嵌套viewpager,viewpager高度不显示
// //解决viewpager高度无法显示问题
// mNestedScrollView.setFillViewport(true);
设置linearlayout在appbarlayout下

2、使用style的方式定义Activity的切换动画定义Application的style

布局就是一个recyclerview

没有解决的问题

share动画,打开的activity是viewpager返回时的图片不对
glide加载网络上的长图时,宽度设置为match失效
glide加载图片时,如果设置图片为match match图片会先显示在上方再移动到中间

 <!-- 系统Application定义 --><application Android:allowBackup="true" Android:icon="@mipmap/ic_launcher" Android:label="@string/app_name" Android:supportsRtl="true" Android:theme="@style/AppTheme">

mainactivity代码:

github:

https://heinika.github.io/
源码:https://github.com/heinika/weibo\_info

定义具体的AppTheme样式其中这里的windowAnimationStyle就是我们定义Activity切换动画的style。而@anim/slide_in_top就是我们定义的动画文件,也就是说通过为Appliation设置style,然后为windowAnimationStyle设置动画文件就可以全局的为Activity的跳转配置动画效果。

图片 2

 <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item><item name="Android:windowAnimationStyle">@style/activityAnim</item> </style><!-- 使用style方式定义activity切换动画 --><style name="activityAnim"><item name="Android:activityOpenEnterAnimation">@anim/slide_in_top</item><item name="Android:activityOpenExitAnimation">@anim/slide_in_top</item> </style>

可以看到就一个初始化布局管理器和设置适配器的代码没什么了(你说没看到初始化控件?看看这篇文章)

而在windowAnimationStyle中存在四种动画:

到这里之前都很好理解,关键就是adapter和点击图片跳转的代码

activityOpenEnterAnimation 用于设置打开新的Activity并进入新的Activity展示的动画activityOpenExitAnimation 用于设置打开新的Activity并销毁之前的Activity展示的动画activityCloseEnterAnimation 用于设置关闭当前Activity进入上一个Activity展示的动画activityCloseExitAnimation 用于设置关闭当前Activity时展示的动画

图片 3图片 4

3.使用ActivityOptions切换动画实现Activity跳转动画通过overridePendingTransition方法基本上可以满足我们日常中对Activity跳转动画的需求了,但MD风格出来之后,overridePendingTransition这种老旧、生硬的方式怎么能适合我们的MD风格的App呢?google在新的sdk中给我们提供了另外一种Activity的过度动画——ActivityOptions。并且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat是一个静态类,提供了相应的Activity跳转动画效果,通过其可以实现不少炫酷的动画效果。在跳转的Activity中设置contentFeature

在API
21以后,我们可以使用内置的Activity切换动画。但是这样也就意味着只能兼容5.0之后的系统,ActivityOptions是一个静态类,它提供了为数不多的几种方法,我们正是用其中的makeSceneTransitionAnimation(Activity
activity,Pair…
sharedElements)来完成了这个效果,有兴趣的小伙伴移步至这里,

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置contentFeature,可使用切换动画 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); Transition explode = TransitionInflater.from.inflateTransition(Android.R.transition.explode);getWindow().setEnterTransition; setContentView(R.layout.activity_three); }

先来说下传递的两个参数,第一个activity不用说,第二个pair<View,String>,View是你开始动画的view对象,string是他的动画名要和结束动画的view名一致才可以,到这里应该可以理解,我们在创建适配器的时候给每个imageview起了一个transitionname当我们跳转至查看大图界面给当前的viewpage赋值相同的名称便能完成动画,然后在我们滑动时更改viewpage的transitionname为对应图片的transitionname这样在点击图片的时候就会显示对应图片的下标。

在startActivity执行跳转逻辑的时候调用startActivity的重写方法,执行ActivityOptions.makeSceneTransitionAnimation方法

发表评论

电子邮件地址不会被公开。 必填项已用*标注