android横向滑动分享,Android将ListView逆时针旋转90°实现横向滑动

053c0af9365f?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

screen4.gif

玩了一段时间Android,最近在实现一些常用的控件封装:项目GitHub地址https://github.com/tikeyc/TikeycAndroid 。这几天想封装一个横向滑动的listView,但发现Android没有像iOS那样的UICollectionView控件,似乎只有一个HorizontalScrollView,后来发现Android有个RecyclerView设置setLayoutManager的setOrientation为HORIZONTAL即可简单实现,不过还是回到最初我的想法去尝试一下。

当然最后肯定是用RecyclerView控件实现(刚学自学Android开发的时候居然没发现RecyclerView,惭愧的很,不过这个控件也是2014年support.v7包出现才有的)。

前期实现思路有:

1.使用GridView添加到HorizontalScrollView上,设置column为item数量count,width为count*itemWidth,这样没有复用性了性能低;

2.根据listView的复用原理,结合HorizontalScrollView自定义一个横向滑动的控件,需要敲一些代码;

中期实现思路:

记得很久以前刚学iOS的时候第一次看到横向滑动的UITableView,想实现它,当时的思路就是将UITableView逆时针旋转90°,然后将UITableViewCell顺时针旋转90°(当然现在肯定是用UICollectionView)。这里我把这个思路用到Android的实现上,将ListView逆时针旋转90°,然后将item顺时针旋转90°,果不其然,成功了!小爽一把。源码地址:https://github.com/tikeyc/TikeycAndroid 封装详情代码见THorizontalListView类

目前还存在一个小问题:就是如果item不是正方形,因为默认旋转是以item中心点旋转,item会出现偏移的问题,需要根据你具体的item的尺寸修改旋转中心点,具体见下面需要了解的技术点.

这里也提一个问题,这个旋转不像iOS那样,iOS先旋转后重新设置想要的frame不会有问题,因初入Android开发,先setRotation,然后旋转后使用setLayoutParams设置想要的frame不成功,旋转中心位置就跟着变了。来个吊大的提供一个方法能像iOS那样。

后期实现思路:

RecyclerView是support.v7包中的控件,可以说是ListView和GridView的增强升级版。RecyclerView设置setLayoutManager的setOrientation为HORIZONTAL即可简单实现

需要了解的技术点:

/**逆时针旋转90°

*setRotation(-90); 默认是已view的中心点旋转,所以先根据最终旋转后显示的位置,先更改view的位置到初始旋转的合适位置,然后再旋转90°就会显示在你所希望的位置

* 如下图:由默认的竖向已中心点旋转为横向

* * * * *

* *

* *

* * * * * * * * * * *

* * * *

* * * *

* * * * * * * * * * *

* *

* *

* * * * *

*/

//此方法用于获取View在Z轴上的旋转角度

public float android.view.View.getRotation()

//此方法用于获取View在X轴上的旋转角度

public float android.view.View.getRotationX()

//此方法用于获取View在Y轴上的旋转角度

public float android.view.View.getRotationY()

//设置View在Z轴上的旋转角度

public void android.view.View.setRotation(float rotation)

//设置View在X轴上的旋转角度

public void android.view.View.setRotationX(float rotationX)

//设置View在Y轴上的旋转角度

public void android.view.View.setRotationY(float rotationY)

//设置View旋转中心点的X坐标。

public void android.view.View.setPivotX(float pivotX)

//设置View旋转中心点的Y坐标。

public void android.view.View.setPivotX(float pivotX)

//设置摄像机的与旋转目标在Z轴上距离

void android.view.View.setCameraDistance(float distance)

具体实现:

package com.tikeyc.tikeycandroid.custom.ScrollView;

import android.content.Context;

import android.graphics.RectF;

import android.os.Handler;

import android.os.Message;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewTreeObserver;

import android.widget.AbsListView;

import android.widget.BaseAdapter;

import android.widget.LinearLayout;

import android.widget.ListView;

/**

* Created by public1 on 2017/6/2.

*/

public class THorizontalListView extends ListView {

private int listView_width;

private int listView_height;

private THorizontalListAdapter horizontalListAdapter;

public THorizontalListView(Context context) {

this(context,null);

}

public THorizontalListView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public THorizontalListView(Context context, @Nullable AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init();

}

@Override

protected void onAttachedToWindow() {

super.onAttachedToWindow();

}

private void init() {

rotationListView();

horizontalListAdapter = new THorizontalListAdapter();

setAdapter(horizontalListAdapter);

}

/**逆时针旋转90°

*setRotation(-90); 默认是已view的中心点旋转,所以先根据最终旋转后显示的位置,先更改view的位置到初始旋转的合适位置,然后再旋转90°就会显示在你所希望的位置

* 如下图:由默认的竖向已中心点旋转为横向

* * * * *

* *

* *

* * * * * * * * * * *

* * * *

* * * *

* * * * * * * * * * *

* *

* *

* * * * *

*/

private void rotationListView() {

ViewTreeObserver viewTreeObserver = getViewTreeObserver();

viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

getViewTreeObserver().removeOnPreDrawListener(this);

int left = getLeft();

int top = getTop();

int right = getRight();

int bottom = getBottom();

int width = right - left;

int height = bottom - top;

Log.e("TAG","getWidth():" + getWidth() + "--" + "getHeight():" + getHeight());

Log.e("TAG","left:" + left + "--" + "top:" + top + "--" + "width:" + width + "--" + "height:" + height);

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();

layoutParams.leftMargin = layoutParams.leftMargin + (width - height)/2;//将view已到默认的旋转中心点

layoutParams.topMargin = layoutParams.topMargin + (height - width)/2;//将view已到默认的旋转中心点

listView_width = width;

listView_height = height;

layoutParams.width = height;//旋转后的宽是旋转前的高

layoutParams.height = width;//旋转后的高是旋转前的宽

setLayoutParams(layoutParams);

Log.e("TAG","left:" + left + "--" + "top:" + top + "--" + "width:" + width + "--" + "height:" + height);

setRotation(-90);

Log.e("TAG","left2:" + getLeft() + "--" + "top2:" + getTop() + "--" + "width:" + width + "--" + "height:" + height);

return true;

}

});

}

public class THorizontalListAdapter extends BaseAdapter {

@Override

public int getCount() {

if (dataSource != null) return dataSource.getCount();

return 0;

}

@Override

public Object getItem(int i) {

if (dataSource != null) return dataSource.getItem(i);

return null;

}

@Override

public long getItemId(int i) {

if (dataSource != null) return dataSource.getItemId(i);

return 0;

}

@Override

public View getView(int i, View view, ViewGroup viewGroup) {

if (dataSource != null) {

view = dataSource.getView(i,view,viewGroup);

//再将item顺时针旋转90° 宽是旋转后的高(item的宽度),高是旋转后的宽(item的高度)

ViewTreeObserver treeObserver = view.getViewTreeObserver();

final View finalView = view;

treeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

@Override

public boolean onPreDraw() {

// int width = finalView.getWidth();

// int height = finalView.getHeight();

// finalView.setPivotX(width/2);

// finalView.setPivotY(listView_height/2);

AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(listView_height,listView_height);

finalView.setLayoutParams(layoutParams);

finalView.setRotation(90);

return true;

}

});

return view;

}

return view;

}

}

private THorizontalListAdapterDatasource dataSource;

public void setDataSource(THorizontalListAdapterDatasource dataSource) {

this.dataSource = dataSource;

horizontalListAdapter.notifyDataSetChanged();

}

public THorizontalListAdapterDatasource getDataSource() {

return dataSource;

}

public interface THorizontalListAdapterDatasource {

int getCount();

Object getItem(int i);

long getItemId(int i);

View getView(int i, View view, ViewGroup viewGroup);

}

}

如何使用:

使用的主要关键代码:

THorizontalListView horizontalListView = (THorizontalListView) mView.findViewById(R.id.tHorizontalListView);

horizontalListView.setBackgroundColor(Color.BLUE);

horizontalListView.setDataSource(new THorizontalListView.THorizontalListAdapterDatasource() {

class ViewHolder {

}

@Override

public int getCount() {

return 20;

}

@Override

public Object getItem(int i) {

return null;

}

@Override

public long getItemId(int i) {

return 0;

}

@Override

public View getView(int i, View view, ViewGroup viewGroup) {

ViewHolder viewHolder;

if (view == null) {

viewHolder = new ViewHolder();

view = View.inflate(getContext(),R.layout.release_home_image_list_item,null);

//宽是高,高是宽

view.setTag(viewHolder);

} else {

viewHolder = (ViewHolder) view.getTag();

}

return view;

}

});

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值