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 实现滚动控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: myeclipse怎么运行c语言,win
- 下一篇: java9 揭秘 jlink_初试Jav