100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > android scrollview居中 使用 HorizontalScrollView 实现滚动控制

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

时间:2023-08-19 11:35:57

相关推荐

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

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

最后的效果如下:

下面逐步上代码:

布局文件 activity_main.xml 如下:

xmlns:tools="/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)如下:

publicclassHSVLayoutextendsLinearLayout{

privateHSVAdapteradapter;

privateContextcontext;

publicHSVLayout(Contextcontext,AttributeSetattrs){

super(context,attrs);

this.context=context;

}

/**

*设置布局适配器

*

*@paramlayoutWidthPerAvatar指定了每一个item的占用宽度

*@paramadapter适配器

*@paramnotify在点击某一个item后的回调

*/

publicvoidsetAdapter(intlayoutWidthPerAvatar,HSVAdapteradapter,

finalINotifySelectItemnotify){

this.adapter=adapter;

for(inti=0;i

finalMapmap=adapter.getItem(i);

Viewview=adapter.getView(i,null,null);

//为视图设定点击监听器

finalintfinalI=i;

view.setOnClickListener(newOnClickListener(){

@Override

publicvoidonClick(Viewv){

//点击选择了某一个Item视图

notify.select(finalI);

}

});

this.setOrientation(HORIZONTAL);

//设置固定显示的每个item布局的宽度

this.addView(view,newLinearLayout.LayoutParams(

layoutWidthPerAvatar,LayoutParams.WRAP_CONTENT));

}

}

}

HSVLayout 中的每一个 视图 item 都是由 HSVAdapter 进行设置的,这个比较简单,只控制了每一个 item 的展示,不影响整个水平滚动视图:

publicclassHSVAdapterextendsBaseAdapter{

privatestaticfinalStringTAG="HSV";

privateList>lstAvatars;

privateContextcontext;

privateintlayoutWidthPerAvatar;

publicHSVAdapter(Contextcontext,intlayoutWidthPerAvatar){

this.context=context;

this.lstAvatars=newArrayList>();

this.layoutWidthPerAvatar=layoutWidthPerAvatar;

}

@Override

publicintgetCount(){

returnlstAvatars.size();

}

@Override

publicMapgetItem(intlocation){

returnlstAvatars.get(location);

}

@Override

publiclonggetItemId(intarg0){

returnarg0;

}

publicvoidaddObject(Mapmap){

lstAvatars.add(map);

notifyDataSetChanged();

}

@Override

publicViewgetView(intlocation,Viewarg1,ViewGrouparg2){

Viewview=LayoutInflater.from(context).inflate(R.layout.user_avatar,null);

view.setLayoutParams(newViewGroup.LayoutParams(layoutWidthPerAvatar,

ViewGroup.LayoutParams.WRAP_CONTENT));

TextViewtvIndex=(TextView)view.findViewById(R.id.index_tv);

tvIndex.setText("index-"+String.valueOf(location));

returnview;

}

}

其对应的布局文件 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:

publicclassMainActivityextendsActionBarActivity

implementsINotifySelectItem{

privatestaticfinalStringTAG="Main";

privateHorizontalScrollViewhsv;

privateHSVLayoutlayoutAvatar;

privateHSVAdapteradapterAvatar;

privateTextViewtvScrollX;

privateintlayoutWidthPerAvatar=0;

privateInteger[]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

};

//记录当前居中的头像索引

privateintcurrentIndex=1;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

intwidth=DisplayUtil.getScreenWidth(this);

intlayoutWidth=(int)(width-getResources().getDimension(R.dimen.activity_horizontal_margin)*2);

//每一个头像占用的宽度

layoutWidthPerAvatar=layoutWidth/3;

hsv=(HorizontalScrollView)findViewById(R.id.hsv);

hsv.setOnTouchListener(newView.OnTouchListener(){

privateintlastScrollX=0;

privateintTouchEventId=-9987832;

Handlerhandler=newHandler(){

@Override

publicvoidhandleMessage(Messagemsg){

super.handleMessage(msg);

if(msg.what==TouchEventId){

if(lastScrollX==hsv.getScrollX()){

//停止滚动,计算合适的位置(采用四舍五入)

intindexScrollTo=Math.round(lastScrollX/(layoutWidthPerAvatar*1.0f));

Log.d(TAG,"stopscroll-"+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

publicbooleanonTouch(Viewv,MotionEventevent){

Log.d(TAG,"touchevent-action:"+event.getAction()

+"|"+event.getX()

+"|"+event.getY()

+"|"+hsv.getScrollX()

+"|"+hsv.getScrollY());

if(event.getAction()==MotionEvent.ACTION_UP){

handler.sendMessageDelayed(handler.obtainMessage(TouchEventId),100);

}

returnfalse;

}

});

layoutAvatar=(HSVLayout)findViewById(R.id.avatar_layout);

adapterAvatar=newHSVAdapter(this,layoutWidthPerAvatar);

for(inti=0;i

Mapmap=newHashMap();

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

publicbooleanonCreateOptionsMenu(Menumenu){

//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.

getMenuInflater().inflate(R.menu.menu_main,menu);

returntrue;

}

@Override

publicbooleanonOptionsItemSelected(MenuItemitem){

//Handleactionbaritemclickshere.Theactionbarwill

//automaticallyhandleclicksontheHome/Upbutton,solong

//asyouspecifyaparentactivityinAndroidManifest.xml.

intid=item.getItemId();

//noinspectionSimplifiableIfStatement

if(id==R.id.action_settings){

returntrue;

}

returnsuper.onOptionsItemSelected(item);

}

@Override

publicvoidselect(intposition){

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;

}

}

}

publicvoidonClickScrollX(Viewview){

tvScrollX.setText("Scroll.x="+String.valueOf(hsv.getScrollX()));

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。