android scrollview居中,使用 HorizontalScrollView 实现滚动控制
功能要求是屏幕上固定显示 3 个 Layout 项(图片+文字),支持点击切换到选择的 Layout 项,并支持滑动切换到最近的 Layout 项。
最后的效果如下:
下面逐步上代码:
布局文件 activity_main.xml 如下:
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
android:layout_height="wrap_content" />
android:id="@+id/hsv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbarStyle="outsideInset">
android:id="@+id/avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/hsv"
android:layout_marginTop="12dp"
android:id="@+id/scrollx_tv"/>
android:onClick="onClickScrollX"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/scrollx_tv"
android:layout_marginTop="12dp"
android:text="滚动位置"/>
上面的 HorizontalScrollView 中使用了自定义的 HSVLayout 布局,定义(HSVLayout.java)如下:
public class HSVLayout extends LinearLayout {
private HSVAdapter adapter;
private Context context;
public HSVLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
/**
* 设置布局适配器
*
* @param layoutWidthPerAvatar 指定了每一个 item 的占用宽度
* @param adapter 适配器
* @param notify 在点击某一个 item 后的回调
*/
public void setAdapter(int layoutWidthPerAvatar, HSVAdapter adapter,
final INotifySelectItem notify) {
this.adapter = adapter;
for (int i = 0; i
final Map map = adapter.getItem(i);
View view = adapter.getView(i, null, null);
// 为视图设定点击监听器
final int finalI = i;
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 点击选择了某一个 Item 视图
notify.select(finalI);
}
});
this.setOrientation(HORIZONTAL);
// 设置固定显示的每个 item 布局的宽度
this.addView(view, new LinearLayout.LayoutParams(
layoutWidthPerAvatar, LayoutParams.WRAP_CONTENT));
}
}
}
HSVLayout 中的每一个 视图 item 都是由 HSVAdapter 进行设置的,这个比较简单,只控制了每一个 item 的展示,不影响整个水平滚动视图:
public class HSVAdapter extends BaseAdapter {
private static final String TAG = "HSV";
private List> lstAvatars;
private Context context;
private int layoutWidthPerAvatar;
public HSVAdapter(Context context, int layoutWidthPerAvatar){
this.context=context;
this.lstAvatars =new ArrayList>();
this.layoutWidthPerAvatar = layoutWidthPerAvatar;
}
@Override
public int getCount() {
return lstAvatars.size();
}
@Override
public Map getItem(int location) {
return lstAvatars.get(location);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
public void addObject(Map map){
lstAvatars.add(map);
notifyDataSetChanged();
}
@Override
public View getView(int location, View arg1, ViewGroup arg2) {
View view = LayoutInflater.from(context).inflate(R.layout.user_avatar,null);
view.setLayoutParams(new ViewGroup.LayoutParams(layoutWidthPerAvatar,
ViewGroup.LayoutParams.WRAP_CONTENT));
TextView tvIndex = (TextView) view.findViewById(R.id.index_tv);
tvIndex.setText("index-" + String.valueOf(location));
return view;
}
}
其对应的布局文件 user_avatar.xml 如下:
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/avatar"/>
android:id="@+id/index_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
最后看一下主页面 MainActivity:
public class MainActivity extends ActionBarActivity
implements INotifySelectItem {
private static final String TAG = "Main";
private HorizontalScrollView hsv;
private HSVLayout layoutAvatar;
private HSVAdapter adapterAvatar;
private TextView tvScrollX;
private int layoutWidthPerAvatar = 0;
private Integer[] p_w_picpaths = {
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar,
R.drawable.avatar
};
// 记录当前居中的头像索引
private int currentIndex = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int width = DisplayUtil.getScreenWidth(this);
int layoutWidth = (int) (width - getResources().getDimension(R.dimen.activity_horizontal_margin) * 2);
// 每一个头像占用的宽度
layoutWidthPerAvatar = layoutWidth / 3;
hsv = (HorizontalScrollView) findViewById(R.id.hsv);
hsv.setOnTouchListener(new View.OnTouchListener() {
private int lastScrollX = 0;
private int TouchEventId = -9987832;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == TouchEventId) {
if (lastScrollX == hsv.getScrollX()) {
// 停止滚动,计算合适的位置(采用四舍五入)
int indexScrollTo = Math.round(lastScrollX/(layoutWidthPerAvatar*1.0f));
Log.d(TAG, "stop scroll - " + lastScrollX
+ "|" + layoutWidthPerAvatar
+ "|" + lastScrollX/(layoutWidthPerAvatar*1.0f)
+ "|" + indexScrollTo);
if (indexScrollTo > 0) {
hsv.smoothScrollTo(indexScrollTo*layoutWidthPerAvatar, 0);
} else {
hsv.smoothScrollTo(0, 0);
}
} else {
handler.sendMessageDelayed(
handler.obtainMessage(TouchEventId), 100);
lastScrollX = hsv.getScrollX();
}
}
}
};
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "touch event - action: " + event.getAction()
+ "|" + event.getX()
+ "|" + event.getY()
+ "|" + hsv.getScrollX()
+ "|" + hsv.getScrollY());
if (event.getAction() == MotionEvent.ACTION_UP) {
handler.sendMessageDelayed(handler.obtainMessage(TouchEventId), 100);
}
return false;
}
});
layoutAvatar = (HSVLayout) findViewById(R.id.avatar_layout);
adapterAvatar = new HSVAdapter(this, layoutWidthPerAvatar);
for (int i = 0; i
Map map = new HashMap();
map.put("p_w_picpath", p_w_picpaths[i]);
map.put("index", (i+1));
adapterAvatar.addObject(map);
}
layoutAvatar.setAdapter(layoutWidthPerAvatar, adapterAvatar, this);
tvScrollX = (TextView) findViewById(R.id.scrollx_tv);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void select(int position) {
Toast.makeText(this, "select " + String.valueOf(position),
Toast.LENGTH_SHORT).show();
if (position > 0) {
if (currentIndex != position) {
hsv.smoothScrollTo((position-1)*layoutWidthPerAvatar, 0);
currentIndex = position;
}
}
}
public void onClickScrollX(View view) {
tvScrollX.setText("Scroll.x = " + String.valueOf(hsv.getScrollX()));
}
}
android scrollview居中,使用 HorizontalScrollView 实现滚动控制相关推荐
- Android ScrollView嵌套ScrollView滚动的问题解决办法
引用:http://mengsina.iteye.com/blog/1707464 http://fenglog.com/article.asp?id=449 Android ScrollView嵌套 ...
- android ScrollView滚动距离和判断滚动停止状态
今天很高兴,自己解决了判断ScrollView滚动停止的监听,现在分享给大家. 因为ScrollView没有像listView中的setOnScrollListener()监听,当然也就没有SCROL ...
- android图片保存形式,Android应用开发之Android ScrollView截图和图片保存到相册的方式...
本文将带你了解Android应用开发之Android ScrollView截图和图片保存到相册的方式,希望本文对大家学Android有所帮助. 1.1首先来看你一种截取屏幕,这种代码有缺陷,只能截取一 ...
- Android TabHost中实现标签的滚动以及一些TabHost开发的奇怪问题
最近在使用TabHost的时候遇到了一些奇怪的问题,在这里总结分享备忘一下. 首先说一点TabActivity将会被FragmentActivity所替代,但是本文中却是使用的TabActivity. ...
- Android ScrollView
Android ScrollView allows us to create a scrollable layout on the android screen. Android ScrollView ...
- Android ScrollView、NestedScrollView、HorizontalScrollView 等
在这篇文章中,我们想看看几个滚动视图的变体或子类以及它们是如何使用的.以下是我们迄今为止涵盖的变体: ScrollView - 超类 NestedScrollView - 子类 Horizonta ...
- Android两个tab吸顶,Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每
Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每 Android scrollView和viewpager嵌套 指示器吸顶 根据viewpager每个 ...
- Android ScrollView嵌套GridView导致GridView只显示一行item
Android ScrollView嵌套GridView导致GridView只显示一行item Android ScrollView在嵌套GridView时候,会导致一个问题发生:GridView只显 ...
- Android——仿淘宝头条垂直滚动广告
淘宝App大家用的都比较多了哈,最近看淘宝头条比较多,就来写个小例子吧. 垂直滚动广告的实现原理其实比较简单,就是定时更新列表内容嘛,然后列表切换的时候再加点炫酷的动画就OK了.如果对Android控 ...
最新文章
- 如何定义带有可选参数的函数python_Python如何定义有可选参数的元类
- Scala模式匹配的亮点——Martin Odersky访谈(四)
- linux mysql忘记root_linux下mysql-5.6忘记root密码,重置root密码详细过程
- 怎么在电脑上使用python-开始在 Windows 上使用 Python(初学者)
- c# 串口最简单接收十六进制
- 我的RHCA之路随想
- (Sql Server)SQL FOR XML PATH
- harris角点检测的学习
- 3.eclipse对mysql云数据库编程增删改查
- Hadoop--xsync分发脚本
- Android演示Stack(课下作业)
- 面试官竟让我用Redis实现一个消息队列!
- EF性能优化-有人说EF性能低,我想说:EF确实不如ADO.NET
- php odbc 结果集处理,php常用ODBC函数集的简单示例
- 蒟蒻7.16题解(选值+遛狗+树上博弈)
- C语言实现约瑟夫环代码
- 软件测试行业前景,人才稀缺
- python if return_python - 使用if-return-return或if-else-return更有效?
- Vue源码笔记之项目架构
- kernel/Makefile:971: recipe for target ‘prepare3‘ failed