十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
功能要求是屏幕上固定显示 3 个 Layout 项(图片+文字),支持点击切换到选择的 Layout 项,并支持滑动切换到最近的 Layout 项。
专注于为中小企业提供成都做网站、网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业永清免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了1000多家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
最后的效果如下:
下面逐步上代码:
布局文件 activity_main.xml 如下:
上面的 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 < adapter.getCount(); i++) { final Mapmap = 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
其对应的布局文件 user_avatar.xml 如下:
最后看一下主页面 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 < p_w_picpaths.length; i++) { Mapmap = 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())); } }