中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用 HorizontalScrollView 實現滾動控制

發布時間:2020-08-05 14:20:46 來源:網絡 閱讀:6920 作者:安靜的瘋子 欄目:移動開發

功能要求是屏幕上固定顯示 3 個 Layout 項(圖片+文字),支持點擊切換到選擇的 Layout 項,并支持滑動切換到最近的 Layout 項。


最后的效果如下:


使用 HorizontalScrollView 實現滾動控制

 

下面逐步上代碼:

 

布局文件 activity_main.xml 如下:

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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">

    <TextView android:text="" android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    
    <HorizontalScrollView
        android:id="@+id/hsv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbarStyle="outsideInset">
        <cn.steven.hsvp_w_picpathswitch.HSVLayout
            android:id="@+id/avatar_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </HorizontalScrollView>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/hsv"
        android:layout_marginTop="12dp"
        android:id="@+id/scrollx_tv"/>
    <Button
        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="滾動位置"/>
</RelativeLayout>

 

上面的 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 Map<String, Object> 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<Map<String,Object>> lstAvatars;
    private Context context;
    private int layoutWidthPerAvatar;

    public HSVAdapter(Context context, int layoutWidthPerAvatar){
        this.context=context;
        this.lstAvatars =new ArrayList<Map<String,Object>>();
        this.layoutWidthPerAvatar = layoutWidthPerAvatar;
    }
    @Override
    public int getCount() {
        return lstAvatars.size();
    }

    @Override
    public Map<String,Object> getItem(int location) {
        return lstAvatars.get(location);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    public void addObject(Map<String,Object> 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 如下:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">
    <ImageView
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:src="@drawable/avatar"/>
    <TextView
        android:id="@+id/index_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" />
</LinearLayout>

 

最后看一下主頁面 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++) {
            Map<String, Object> map = new HashMap<String, Object>();
            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()));
    }
}

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

日照市| 体育| 辰溪县| 集贤县| 台湾省| 大兴区| 博乐市| 英山县| 北宁市| 道孚县| 萝北县| 江永县| 清水县| 高邑县| 鄱阳县| 佛冈县| 东乌| 麦盖提县| 高碑店市| 黔东| 汉沽区| 松桃| 比如县| 吉木萨尔县| 墨江| 共和县| 中卫市| 南部县| 永德县| 利川市| 石城县| 迁安市| 察雅县| 响水县| 若羌县| 潍坊市| 班玛县| 长丰县| 哈密市| 栾川县| 拉萨市|