android scrollview居中,使用 HorizontalScrollView 实现滚动控制

功能要求是屏幕上固定显示 3 个 Layout 项(图片+文字),支持点击切换到选择的 Layout 项,并支持滑动切换到最近的 Layout 项。

最后的效果如下:

2066bb9c8331e4bc876bcff9deeff175.png

下面逐步上代码:

布局文件 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()));

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/498811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统鸿蒙生态链,任正非透露鸿蒙系统细节,比安卓速度快60%,两三年建好生态链...

原标题:任正非透露鸿蒙系统细节,比安卓速度快60%,两三年建好生态链华为鸿蒙系统自被曝光以来,就引起全球媒体极大关注。关于鸿蒙系统的相关细节,目前大多只限于猜测和知情人士透露的些许信息。不过,近期华为…

数值传热学陶文铨pdf_西安交大陶文铨当选“2019最美科技工作者”

未来网高校频道8月12日讯(记者 杨子健 通讯员 张玥)近日,由中央宣传部、中国科学技术协会、中华人民共和国科学技术部、中国科学院、中国工程院、国家国防科技工业局联合开展“最美科技工作者”学习宣传活动,共遴选出10位2019年“最美科技工作者”。据了…

mysql load data infile 导入数据 某一列 空_Sql数据挑战赛amp;网络销售案例分析

SQL挑战赛第一期:1: 编写一个查询&#xff0c;列出员工姓名列表&#xff0c;员工每月工资超过2000美元且员工工作时间少于10个月。通过提升employee_id对结果进行排序select name from employee where salary > 2000 and months < 10 order by employee_id;2: 查询 Emplo…

html项目列表页面源码,HTML 列表

HTML 列表HTML 支持有序、无序和定义列表:HTML 列表有序列表第一个列表项第二个列表项第三个列表项无序列表列表项列表项列表项在线实例无序列表本例演示无序列表。有序列表本例演示有序列表。(可以在本页底端找到更多实例。)HTML无序列表无序列表是一个项目的列表&#xff0c;…

html用转义字符画菱形,JavaScript生成字符画(ASCII Art)

今天玩一些新的东西&#xff0c;大家都没有看过这样的视频&#xff1a;或者 这样的图片&#xff1a;网上有很多生成这种图片/视频的工具&#xff0c;但是每个程序员都有一颗造轮子的心&#xff0c;我们当然要玩出自己的花样啦。老规矩&#xff0c;还是先讲原理&#xff0c;建议…

微信更新对html影响,微信再次大更新 将极大影响用户使用习惯

[导读]微信再次迎来历史性大更新&#xff0c;小程序终于展露腾讯野心&#xff01;微信再次迎来历史性大更新&#xff0c;小程序终于展露腾讯野心!...微信小程序桌面在昨日1月22日晚&#xff0c;微信更新7.0.3版本&#xff0c;腾讯在App Store中只表示&#xff1a;本次是一次小更…

什么叫pmt测试分析_RVS — 面向目标硬件的软件性能测试工具

Rapita Verification Suite(简称&#xff1a;RVS)&#xff0c;为英国Rapita Systems公司提供的一款嵌入式系统在板测试套件。其产品符合ISO-26262、IEC-61508等行业标准&#xff0c;兼容Vxworks、Linux、SYSBIOS 等操作系统&#xff0c;支持C、C、Ada多种语言&#xff0c;多方位…

版本不见了_王者荣耀复古版本来袭?第四代主宰形象回归!可以给小兵加速

山河不足重&#xff0c;重在遇知已。好久不见&#xff0c;别来无恙来自小助理的文章推送~时值中秋&#xff0c;先祝大家中秋节快乐&#xff01;王者荣耀的新版本即将上线&#xff0c;不知道大家还记不记得新版本将会上线很多新的东西&#xff0c;峡谷路线更改&#xff0c;鼓励同…

python从小到大的顺序输出_「小白专栏」Python中使用for循环,为什么输出结果不是按顺序?...

欢迎各位小哥哥小姐姐阅读本的文章,对大家学习有帮助,请点赞加关注哦!!!!!!!!!!您的点赞和关注将是我持续更新的动力呢.^v^有不懂的问题可以私聊我哦!前言如图&#xff0c;为什么输出的不是按Jen, Sarah, Phil, Edward的顺序呢&#xff1f;大家可以先想想为什么&#xff1f;思考…

雷库兹韦尔量子计算机,熬到2045年,人类可能靠人工智能战胜死亡了

这几天差评君在网上冲浪的时候&#xff0c;无意间挖到了这一张坟图。虽然这已经是五六年前的老梗了&#xff0c;但依旧今人唏嘘不已&#xff0c;毕竟这些年来的技术发展真的是又快又粗暴。让人不由得想像公知们一样阴阳怪气一番&#xff1a;科技啊&#xff0c;请你慢些走&#…

elxel表格纸张尺寸_一本书的诞生:纸张知识

平张纸的数量以令来计算&#xff0c;不论纸张(百科)大小&#xff0c;每500张为一令。卷筒纸的数量通常以吨来计算&#xff0c;即用重量来反映数量。单张纸的重量以每平方米的克重来表示&#xff0c;单位是gsm&#xff0c;即g&#xff0f;m2&#xff0c;如果说80g的纸,就是每平方…

追加的英文计算机,Latex同时添加中英文摘要

注重版权&#xff0c;若要转载烦请附上作者和链接作者&#xff1a;Joshua_yi链接&#xff1a;https://blog.csdn.net/weixin_44984664/article/details/106168468哎&#xff0c;已经步入了开始写论文的年纪了&#xff0c;从之前的上传作业也慢慢变成了上交论文第一次用latex这玩…

React 路由

引言 在我们之前写的页面当中&#xff0c;用我们的惯用思维去思考的话&#xff0c;可能会需要写很多的页面&#xff0c;例如做一个 tab 栏&#xff0c;我们可能会想每个选项都要对应一个 HTML 文件&#xff0c;这样会很麻烦&#xff0c;甚至不友好&#xff0c;我们把这种称为 …

清华大学06届 计算机王煜,祝贺!这两位三年前从超银中学毕业的学霸,今年被清华大学“破格”录取啦...

青岛日报社/观海新闻8月13日讯 今年是“强基计划”首年招生&#xff0c;“强基计划”属于单独批次录取&#xff0c;也是高考所有批次录取中最早公布结果的&#xff0c;一经录取&#xff0c;就不再参加后续高考志愿录取投档。观海新闻记者从超银中学获悉&#xff0c;青岛二中今年…

jmeter web服务器协议,【JMeter4.0学习(三)】之SoapUI创建WebService接口模拟服务端以及JMeter测试SOAP协议性能测试脚本开发(示例代码)...

目录&#xff1a;【阐述】&#xff1a;首先应该遇到了一个共同的问题&#xff0c;JMeter3.2之后就没有WebService(SOAP) Request,后来经过查询网上资料得知其实可以用HTTP请求来操作&#xff0c;结果是一样的。【步骤】&#xff1a;一、创建WebService接口模拟服务端如果大家有…

flask bootstrap ajax,使用Flask集成bootstrap的方法

1. 下载flask-bootstrappip install flask-bootstrap2. 找到base.html文件将site-packages\flask_bootstrap\templates文件夹下的bootstrap目录copy到你的项目\templates目录下&#xff0c;确保bootstrap目录下包含base.html文件&#xff0c;因为我们后面要用到。3. 代码user.h…

chrome切换前端模式_H5暗黑模式在京东收银台中的实践

背景暗黑主题下&#xff0c;用户可以选择采用深色的系统范围外观而不是浅色外观。在暗黑模式下&#xff0c;系统对所有窗口&#xff0c;视图&#xff0c;菜单和控件采用较暗的调色板。谷歌的 Gmail 和 Chrome 浏览器、聊天工具 slack、telegram、Edge 浏览器和 Office 移动版 A…

使用udp协议实现服务器端程序时,用VisualC#实现UDP协议(二)

12.并以下面代码替换Form.cs中由系统产生的InitializeComponent过程。private void InitializeComponent ( ){this.button1 new System.Windows.Forms.Button ( ) ;this.button2 new System.Windows.Forms.Button ( ) ;this.textBox1 new System.Windows.Forms.TextBox ( ) …

魅族16无信号服务器,魅族16信号差的解决办法

手机信号问题一直都是人们关注的问题&#xff0c;在日常使用时有些地方手机可能出现突然信号变差&#xff0c;可能别人的手机信号一直很好只有你的出现了问题。魅族手机最早的几个版本都很容易出现这种问题&#xff0c;新款的魅族16怎么样呢&#xff1f;魅族16信号差怎么解决呢…

服务器系统核心和带gui区别,Windows Server 2012图形用户界面(GUI)和服务器核心(Server Core)之间的切换...

当安装 Windows Server 2012 时&#xff0c;咱们能够在“服务器核心安装”和“彻底安装”之间任选其一。“带 GUI 选项的服务器”选项Windows Server 2012 等效于 Windows Server 2008 R2 中的彻底安装选项。“服务器核心安装”选项可减小所需的磁盘空间、潜在的***面&#xff…