1. 程式人生 > >android中可左右滑動輸入框

android中可左右滑動輸入框

  在網上無意看到一個UI動畫,使用者輸入身份證資訊時可以左右滑動輸入框進行輸入,並且資訊可以實時顯示。閒下之餘,自己就動手用程式碼實現出來了,廢話不多說,開始講講如何實現製作的。
網上例項圖

1,佈局製作
  先寫一個主介面avtivity_main,這裡只是顯示介面,為了便於實現互動,使用FrameLayout實現主要介面,佈局填充。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height
="match_parent" android:layout_gravity="center" android:orientation="vertical">
<LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:background="#FC9B18" android:gravity="center" android:orientation="horizontal"
>
<TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="身份證資訊" android:textColor="#fff" android:textSize="22sp" /> </LinearLayout> <LinearLayout
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout android:id="@+id/frame" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </LinearLayout> </LinearLayout>

  下面是主要介面fragment_pager,用於展示輸入介面和顯示輸入內容,沒有使用權重,因為彈出的輸入框是放在ViewPager中,如果使用權重比例,會影響效果。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EFEFEF"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="180dp"
        android:layout_marginLeft="22dp"
        android:layout_marginRight="22dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/papers_bag"
        android:orientation="vertical"
        android:paddingLeft="22dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="證件資訊"
            android:textColor="#9fffffff"
            android:textSize="16sp" />

        <View
            android:layout_width="190dp"
            android:layout_height="1dp"
            android:layout_marginTop="8dp"
            android:background="#80ffffff" >
        </View>

        <LinearLayout
            style="@style/papers_bag"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                style="@style/papers_textview_type"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="姓名" />

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:text="唯一"
                android:textColor="#80ffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            style="@style/papers_bag"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                style="@style/papers_textview_type"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="證件型別" />

            <TextView
                android:id="@+id/tv_pager"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:text="身份證"
                android:textColor="#80ffffff"
                android:textSize="14sp" />
        </LinearLayout>

        <LinearLayout
            style="@style/papers_bag"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                style="@style/papers_textview_type"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="證件號碼" />

            <TextView
                android:id="@+id/tv_nume"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="4dp"
                android:text="4654986546549894"
                android:textColor="#80ffffff"
                android:textSize="14sp" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_erview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipChildren="false"
        android:gravity="center_horizontal"
        android:orientation="vertical" >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:clipChildren="false"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:visibility="gone" >
        </android.support.v4.view.ViewPager>

        <TextView
            android:id="@+id/tv_sname"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="10dp"
            android:background="@drawable/shape_rectangle"
            android:gravity="center_vertical"
            android:paddingLeft="20dp"
            android:text="姓名"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_spager"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="16dp"
            android:background="@drawable/shape_rectangle"
            android:gravity="center_vertical"
            android:paddingLeft="20dp"
            android:text="證件型別"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_snume"
            android:layout_width="match_parent"
            android:layout_height="55dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="16dp"
            android:background="@drawable/shape_rectangle"
            android:gravity="center_vertical"
            android:paddingLeft="20dp"
            android:text="證件號"
            android:textSize="12sp"
            android:visibility="visible" />

        <Button
            android:id="@+id/bt_next"
            android:layout_width="320dp"
            android:layout_height="55dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_marginTop="16dp"
            android:background="@drawable/identity_selector"
            android:text="下一步"
            android:textColor="#ffffff"
            android:textSize="24sp" >
        </Button>
    </LinearLayout>

</LinearLayout>

左右滑動輸入佈局item,在ViewPager中放置控制元件EditView,詳見程式碼例項

2、程式碼邏輯
  一個Activity,一個Fragment,當然使用ViewPager肯定少不了Adapter,將主要程式碼編寫在裡Fragment中,這裡實現主要邏輯。
  在Adapter中EditPagerAdapter繼承PargerAdapter,重寫instantiateItem()方法,將ItemView初始化成ViewPager物件。這樣含有EditView的ViewPager就可以實現左右滑動的效果。  

@Override
    public Object instantiateItem(ViewGroup container, int position) {
        position = position % listView.size();
        if (position < 0) {
            position = listView.size() + position;
        }
        View view = listView.get(position);
        // 如果View已經在之前新增到了一個父元件,則必須先remove,否則會丟擲IllegalStateException。
        ViewParent vp = view.getParent();
        if (vp != null) {
            ViewGroup parent = (ViewGroup) vp;
            parent.removeView(view);
        }
        ((ViewPager) container).addView(view);

        return view;
    }

  DepthPageTransformer是網上找到的工具類,來實現ViewPager兩側若隱若現的效果,通過viewpager中setPageMargin()方法,傳入設定的間距,可使效果更加明顯。

  這裡講一下ViewPager中EditView與軟鍵盤的互動:
  1.在身份證、姓名等的地方是TextView,當點選時同時彈出ViewPager與軟鍵盤
  2.根據軟鍵盤隱藏和顯示,整個view佈局發生的高度變化,來判斷ViewPager顯示狀態
  注意:初始化ViewPager中EditView以及鍵盤焦點獲取必須要在Activity生命週期onResume()中,因為在oncreate中View.getWidth和View.getHeight無法獲得一個view的高度和寬度,這是因為View元件佈局要在onResume回撥後完成。

  通過getViewTreeObserver().addOnGlobalLayoutListener()來獲得寬度或者高度。這是獲得整體view的寬度和高度的方法之一。
  OnGlobalLayoutListener 是ViewTreeObserver的內部類,當一個檢視樹的佈局發生改變時,可以被ViewTreeObserver監聽到,這是一個註冊監聽檢視樹的觀察者(observer),在檢視樹的全域性事件改變時得到通知。ViewTreeObserver不能直接例項化,而是通過getViewTreeObserver()獲得。

  這裡定義為大於或小於500時,也可以實現大於小於佈局整體高度的三分之一,這樣更有利於適配。

// 根據介面彈出鍵盤佈局整體高度發生變化來判斷當鍵盤彈出時顯示輸入框,當鍵盤隱藏時同時隱藏滑動輸入框
        mainView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {

                    @Override
                    public void onGlobalLayout() {
                        // TODO Auto-generated method stub
                        int heightDill = mainView.getRootView().getHeight()
                                - mainView.getHeight();
                        int height = mainView.getRootView().getHeight();
                        int height2 = mainView.getHeight();
                        //
                        if (heightDill > 500) {
                            viewpager.setVisibility(View.VISIBLE);
                        } else {
                            viewpager.setVisibility(View.GONE);
                        }
                    }
                });

  下面是獲取軟鍵盤的方法,當點選身份證、姓名等的地方TextView獲取軟鍵盤。

private void getSoftKef(final View v) {
        InputMethodManager m = (InputMethodManager) v.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        m.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }
private void initView(int num) {
        for (int i = 0; i < num; i++) {
            View itemView = View.inflate(getActivity(),
                    R.layout.viewpager_item, null);
            TextView tv_item = (TextView) itemView.findViewById(R.id.tv_item);
            et_item = (EditText) itemView.findViewById(R.id.et_item);

            et_item.requestFocus();

            //給editText獲取軟鍵盤焦點
            final InputMethodManager intputManager = (InputMethodManager) et_item
                    .getContext()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);

            ImageView iv_item = (ImageView) itemView.findViewById(R.id.iv_item);

            if (i == 0) {
                tv_item.setText("姓名");
                onTextWatcher(tv_name, tv_sname);
                iv_item.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        viewpager.setCurrentItem(1);
                    } 
                });
            } else if (i == 1) {
                tv_item.setText("證件型別");
                onTextWatcher(tv_pager, tv_spager);
                iv_item.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        viewpager.setCurrentItem(2);
                    }
                });

            } else if (i == 2) {
                tv_item.setText("證件號");
                onTextWatcher(tv_nume, tv_snume);
                iv_item.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        intputManager.hideSoftInputFromWindow(
                                et_item.getWindowToken(), 0);
                    }
                });
            }
            listView.add(itemView);
        }
    }

3**總結**

  此例項充分運用ViewPager左右滑動的效果,Fragment,檢視樹監聽整體佈局的變化來實現,使輸入框更加炫酷,運用在專案也是不錯的動畫效果,不足之處螢幕適配不夠好,在2560*1440畫素中,滑動的ViewPager會變的比較小,而且在底部與軟鍵盤間距較大。這個問題後期需要優化,有興趣的朋友有什麼好的方案可以給我留言

                                 我是一隻奮鬥的菜鳥