Android XPopup彈窗

XPopup

Android 開發過程中會遇到各種各樣的需求,那麼,如果當你擁有一個產品經理非常喜歡各種小提示的時候(沒錯,我的上個產品就是這樣,美其名曰用戶體驗),你就會用到彈窗,各種彈窗,哪裏都有彈窗!!!一開始我封裝了一個小型彈窗來實現他的需求,到後來,變本加厲,我的小彈窗根本不夠用。

然後,直到我遇見了她!XPopup,是她拯救我於水火之中,讓我感受到了人間冷暖。接下來,就讓我們一起來康康簡單的入門使用吧。

XPopup

食用方法

一如既往的添加Gradle依賴:

implementation 'com.lxj:xpopup:1.9.0' //就是androidx版本
//從1.8.12開始,包變爲androidx版本,且只提供androidx版本。
//從1.8.12開始,包變爲androidx版本,且只提供androidx版本。
//從1.8.12開始,包變爲androidx版本,且只提供androidx版本。

//for androidx.
//implementation 'com.lxj:xpopup:1.8.10-x'  //從1.8.12開始,沒有-x版本了

必須添加的依賴庫:

//版本號在26以及以上即可
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'

以上導入,build完成就可以使用了,更詳細的使用方法建議去他的GitHub官網查看,接下來我說說我在使用過程中總結的一些心得和一些常用的彈窗編寫分享。

最普通的彈窗 (確認,取消)

這種彈窗是最普通,也是最好用的,他的組成就四個部分,title(標題)、content(文案)、confirm(確認)、cancel(取消),對應的佈局裏面,必須包含的TextView以及id有:tv_title,tv_content,tv_cancel,tv_confirm

R.layout.my_confim_popup

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/dialog_confirm"
    android:orientation="vertical">


    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:textColor="#ff333333"
        android:textSize="14sp"
        tools:text="測試標題" />

    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="35dp"
        android:layout_marginTop="15dp"
        android:layout_marginRight="35dp"
        android:layout_marginBottom="15dp"
        android:gravity="center"
        android:padding="10dp"
        android:textColor="#ff333333"
        android:minHeight="100dp"
        android:textSize="14sp"
        tools:text="測試內容" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#F7F7F7" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp">

        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="取消"
            android:textSize="14sp" />

        <View
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="#F7F7F7" />

        <TextView
            android:id="@+id/tv_confirm"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="確認"
            android:textColor="#f00"
            android:textSize="14sp" />
    </LinearLayout>

</LinearLayout>
new XPopup.Builder(getActivity())
                        .maxWidth((int) (ScreenUtils.getScreenWidth() * 0.7))
                        .asConfirm("title", "content",
                                "confirmBtnText",
                                "cancelBtnText",
                                new OnConfirmListener() {
                                    @Override
                                    public void onConfirm() {
                                        ToastUtils.showShort("confirmListener");
                                    }
                                },
                                new OnCancelListener() {
                                    @Override
                                    public void onCancel() {
                                        ToastUtils.showShort("cancelListener");
                                    }
                                }, false)
                        .bindLayout(R.layout.my_confim_popup)
                        .show();

 效果圖

上面呢是最簡單的使用方法,其中maxWidth表示的是彈窗所在屏幕寬度佔比,下面貼一段他項目裏面的源碼,相關的數據參數一眼就能看懂啦!

/**
         * 顯示確認和取消對話框
         *
         * @param title           對話框標題,傳空串會隱藏標題
         * @param content         對話框內容
         * @param cancelBtnText   取消按鈕的文字內容
         * @param confirmBtnText  確認按鈕的文字內容
         * @param confirmListener 點擊確認的監聽器
         * @param cancelListener  點擊取消的監聽器
         * @param isHideCancel    是否隱藏取消按鈕
         * @return
         */
        public ConfirmPopupView asConfirm(CharSequence title, CharSequence content, CharSequence cancelBtnText, CharSequence confirmBtnText, OnConfirmListener confirmListener, OnCancelListener cancelListener, boolean isHideCancel) {
            popupType(PopupType.Center);
            ConfirmPopupView popupView = new ConfirmPopupView(this.context);
            popupView.setTitleContent(title, content, null);
            popupView.setCancelText(cancelBtnText);
            popupView.setConfirmText(confirmBtnText);
            popupView.setListener(confirmListener, cancelListener);
            if (isHideCancel) popupView.hideCancelBtn();
            popupView.popupInfo = this.popupInfo;
            return popupView;
        }

        public ConfirmPopupView asConfirm(CharSequence title, CharSequence content, OnConfirmListener confirmListener, OnCancelListener cancelListener) {
            return asConfirm(title, content, null, null, confirmListener, cancelListener, false);
        }

        public ConfirmPopupView asConfirm(CharSequence title, CharSequence content, OnConfirmListener confirmListener) {
            return asConfirm(title, content, null, null, confirmListener, null, false);
        }

CenterPopupView

當最原始的彈窗滿足不了你的需求時,這時候你就需要自定義彈窗啦,使用方法也很簡單,新建一個類繼承CenterPopupView就行了,同樣的還有BottomPopupView,AttachPopupView/HorizontalAttachPopupView,DrawerPopupView,PartShadowPopupView,FullScreenPopupView

這裏我就貼一段我在開發過程中使用到最多的支付密碼彈窗(簡陋不堪。。。):

R.layout.dialog_pay_password

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/shape2">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/shape2"
        android:orientation="vertical"
        >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:orientation="horizontal">

            <View
                android:layout_width="50dp"
                android:layout_height="1dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:background="@color/line" />

            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="請輸入支付密碼"
                android:textColor="@color/gray_9191"
                android:textSize="14sp" />

            <View
                android:layout_width="50dp"
                android:layout_height="1dp"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="15dp"
                android:layout_marginRight="15dp"
                android:background="@color/line" />

        </LinearLayout>

        <TextView
            android:id="@+id/tv_money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="15dp"
            android:textStyle="bold"
            tools:text="¥ 1234元"
            android:textColor="@color/normal_text"
            android:textSize="20sp" />

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_marginTop="15dp"
            android:layout_height="50dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            app:cardCornerRadius="5dp"
            >
            <EditText
                android:id="@+id/et_pwd"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:hint="請輸入支付密碼"
                android:inputType="textPassword"
                android:background="@null"
                android:textColorHint="@color/gray_9191"
                android:textSize="14sp" />

        </androidx.cardview.widget.CardView>



        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:layout_marginTop="10dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tv_cancel"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:background="@color/white"
                android:gravity="center"
                android:text="取消"
                android:textColor="@color/normal_text"
                android:textSize="14sp" />

            <View
                android:layout_width="1dp"
                android:layout_height="30dp"
                android:layout_marginTop="1dp"
                android:layout_marginBottom="1dp"
                android:background="@color/line" />

            <TextView
                android:id="@+id/tv_confirm"
                android:layout_width="0dp"
                android:layout_height="40dp"
                android:layout_weight="1"
                android:background="@color/white"
                android:gravity="center"
                android:text="確認"
                android:textColor="@color/red"
                android:textSize="14sp" />
        </LinearLayout>


    </LinearLayout>


</FrameLayout>

PayPasswordDialog

import android.content.Context;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.lxj.xpopup.core.CenterPopupView;

import cn.sunsapp.owner.R;


public class PayPasswordDialog extends CenterPopupView {


    private String mMoney = "";
    private String mTitle = "";
    private EditText etPwd;

    public PayPasswordDialog(@NonNull Context context, String money, String title) {
        super(context);
        mTitle = title;
        mMoney = money;
    }


    @Override
    protected int getImplLayoutId() {
        return R.layout.dialog_pay_password;
    }

    @Override
    protected void onCreate() {
        super.onCreate();
        ((TextView) findViewById(R.id.tv_title)).setText(mTitle);
        ((TextView) findViewById(R.id.tv_money)).setText("¥ "+mMoney);

        findViewById(R.id.tv_cancel).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                PayPasswordDialog.this.dismiss();
            }
        });

        etPwd = (EditText) findViewById(R.id.et_pwd);
        findViewById(R.id.tv_confirm).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mListener != null) {
                    mListener.onConfirm(etPwd.getText().toString());
                }
            }
        });
    }

    private OnConfirnListener mListener = null;

    public PayPasswordDialog setOnConfirmListener(OnConfirmListener listener){

        mListener = listener;
        return this;
    }

    public interface OnConfirmListener{
        void onConfirm(String pwd);
    }
}

使用過程中可能會遇到一些彈窗在屏幕裏面佔比或大或小的局面,這時候你可以重寫一下他裏面的一個getMaxWidth()方法,效果和上面的那個maxWidth一樣

@Override
    protected int getMaxWidth() {
        return (int) (XPopupUtils.getWindowWidth(getContext()) * 0.8f);
    }

使用:

PayPasswordDialog payPasswordDialog = new PayPasswordDialog(mContext, payNumEditTextValue, "餘額提現").setOnConfirmListener(new PayPasswordDialog.OnConfirmListener() {
            @Override
            public void onConfirm(String pwd) {
                dismiss();
                ToastUtils.showShort("提現密碼"+pwd);
            }
        });

        new XPopup.Builder(mContext)
                .asCustom(payPasswordDialog)
                .show();

重磅登場

MapDialog

這是一個基於FullScreenPopupView的全屏地圖選擇彈窗,因爲我是做物流軟件的,所以很多地方都會用到地圖選擇器,無論是地圖選點還是三級聯動選擇地址,如果你單獨另起一個界面的話,數據回傳還有複用等功能處理起來都很麻煩,這時候就輪到彈窗登場了。將地圖選擇器封裝成一個彈窗的話,不僅能降低成本,在處理回傳數據的時候利用回調,還不是想怎麼樣就怎麼樣!使用起來也不用每次新開一個界面了,只需new 一個彈窗就好啦,還不是美滋滋。

只不過美中不足的就是,這個彈窗不能在一級頁面,也就是app啓動之後進入的首頁使用,不然的話,在用戶使用手勢返回的時候,很容易導致退出app。還有一點就是它消失的動畫是從上往下消失的,這一點我暫時還沒做改動。好了,廢話不多說,上代碼:

R.layout.dialog_map

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="@color/red"/>

    <include layout="@layout/toolbar" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/white"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_search_city_poi"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="8dp"
            android:layout_marginRight="15dp"
            android:layout_marginBottom="8dp"
            android:layout_weight="1"
            android:background="#FFF6F6F6"
            android:drawableLeft="@drawable/search"
            android:drawablePadding="11dp"
            android:ellipsize="end"
            android:hint="請輸入網點地址"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:textColor="@color/normal_text"
            android:textColorHint="#FFC2C2C2"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/tv_ensure_commit_btn"
            style="@style/style_tv_no_font_padding"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginTop="8dp"
            android:layout_marginRight="15dp"
            android:layout_marginBottom="8dp"
            android:background="@drawable/shaper_radius5_red_bg"
            android:gravity="center"
            android:paddingLeft="8dp"
            android:paddingRight="8dp"
            android:text="確認"
            android:textColor="@color/white"
            android:textSize="14sp" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_map_and_poi_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="gone">

        <com.amap.api.maps.MapView
            android:id="@+id/mv_branch_address_choose"
            android:layout_width="match_parent"
            android:layout_height="250dp" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_branch_address_choose"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ll_search_place"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_search_by_input_text"
            android:layout_width="match_parent"
            android:background="@color/white"
            android:layout_height="match_parent" />
    </LinearLayout>

</LinearLayout>

MapDialog

import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapOptions;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.basic.lattercore.activities.BaseActivity;
import com.basic.lattercore.app.Suns;
import com.basic.lattercore.util.SunsToastUtils;
import com.basic.lattercore.util.click.AntiShakeUtils;
import com.basic.lattercore.util.event.EventBusUtils;
import com.basic.lattercore.util.event.EventMessage;
import com.blankj.utilcode.util.KeyboardUtils;
import com.blankj.utilcode.util.LogUtils;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.google.android.material.appbar.MaterialToolbar;
import com.lxj.xpopup.impl.FullScreenPopupView;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import cn.sunsapp.owner.EventCode;
import cn.sunsapp.owner.R;
import cn.sunsapp.owner.adapter.PoiListAdapter;
import cn.sunsapp.owner.adapter.SearchPlaceListAdapter;


public class MapDialog extends FullScreenPopupView {

    private EditText etSearchCityPoi;
    private TextView tvEnsureCommitBtn;
    private LinearLayout llMapAndPoiList;
    private LinearLayout llSearchPlace;
    private MapView mapView;
    private RecyclerView rvSearchByInputText;
    private RecyclerView rvBranchAddressChoose;

    private AMap aMap = null;

    // 定位adapter
    private PoiListAdapter poiListAdapter;

    private SearchPlaceListAdapter searchAdapter;

    private Double mLat = 0.0;

    private Double mLng = 0.0;

    private WeakHashMap<String, Object> eventMap = new WeakHashMap<>();


    public MapDialog(@NonNull Context context) {
        super(context);
    }

    public MapDialog(@NonNull Context context, Double lat, Double lng) {
        super(context);
        this.mLat = lat;
        this.mLng = lng;

    }

    @Override
    protected int getImplLayoutId() {
        return R.layout.dialog_map;
    }

    @Override
    protected void onCreate() {
        super.onCreate();

        // id綁定
        bindView();

        // 初始化recycleview
        initView();

        // 輸入框字符變化
        searchRange();

        // 初始化mapview
        initMap(new Bundle());

        // 確認按鈕
        clickEnsure();

        KeyboardUtils.hideSoftInput(this);
    }

    private void bindView() {
        TextView toolbarTitle = (TextView) findViewById(R.id.toolbar_title);
        MaterialToolbar toolbar = (MaterialToolbar) findViewById(R.id.toolbar);

        toolbarTitle.setText("地圖選擇");

        toolbar.setNavigationIcon(com.basic.core.R.drawable.icon_back_white);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MapDialog.this.dismiss();
            }
        });

        etSearchCityPoi = (EditText) findViewById(R.id.et_search_city_poi);
        tvEnsureCommitBtn = (TextView) findViewById(R.id.tv_ensure_commit_btn);
        llMapAndPoiList = (LinearLayout) findViewById(R.id.ll_map_and_poi_list);
        llSearchPlace = (LinearLayout) findViewById(R.id.ll_search_place);
        mapView = (MapView) findViewById(R.id.mv_branch_address_choose);
        rvSearchByInputText = (RecyclerView) findViewById(R.id.rv_search_by_input_text);
        rvBranchAddressChoose = (RecyclerView) findViewById(R.id.rv_branch_address_choose);


        // 進入頁面時隱藏搜索recycleview,顯示地圖和對應的poi recycleview
        llMapAndPoiList.setVisibility(View.VISIBLE);
        llSearchPlace.setVisibility(View.GONE);
    }

    /**
     * 實例化mapview,顯示地圖
     *
     * @param savedInstanceState
     */
    private void initMap(Bundle savedInstanceState) {

        mapView = (MapView) findViewById(R.id.mv_branch_address_choose);
        mapView.onCreate(savedInstanceState);

        if (aMap == null) {
            aMap = mapView.getMap();
        }
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位藍點樣式類myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//連續定位、且將視角移動到地圖中心點,定位點依照設備方向旋轉,並且會跟隨設備移動。(1秒1次定位)如果不設置myLocationType,默認也會執行此種模式。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        myLocationStyle.showMyLocation(false);
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));

        mapView.getMap().setMyLocationEnabled(true);
        mapView.getMap().setMyLocationStyle(myLocationStyle);
        mapView.getMap().getUiSettings().setMyLocationButtonEnabled(true);
        mapView.getMap().getUiSettings().setZoomControlsEnabled(false);
        mapView.getMap().getUiSettings().setScaleControlsEnabled(true);//顯示比例尺
        mapView.getMap().getUiSettings().setLogoPosition(AMapOptions.LOGO_POSITION_BOTTOM_RIGHT);//設置地圖logo的顯示位置爲右下角(隱藏不了)
        mapView.getMap().moveCamera(CameraUpdateFactory.zoomTo(18f));

        mapView.getMap().setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
            @Override
            public void onMyLocationChange(Location location) {
                if (location == null) {
                    return;
                }
                Marker marker;
                MarkerOptions markerOptions;
                markerOptions = new MarkerOptions();
                marker = mapView.getMap().addMarker(markerOptions);

                int width = mapView.getRight() / 2;
                int height = mapView.getBottom() / 2;
                marker.setPositionByPixels(width, height);

                LatLng latLng = null;
                if (mLat == 0.0) {
                    latLng = new LatLng(location.getLatitude(), location.getLongitude());
                } else {
                    latLng = new LatLng(Double.valueOf(mLat), Double.valueOf(mLng));
                }
                moveCameraUpdate(mapView, latLng, 18f);
                mapView.getMap().setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
                    @Override
                    public void onCameraChange(CameraPosition cameraPosition) {

                    }

                    @Override
                    public void onCameraChangeFinish(CameraPosition cameraPosition) {
                        if (cameraPosition == null) {
                            return;
                        }
                        LatLng target = cameraPosition.target;
                        getCircumInfo(getContext(), target.latitude, target.longitude);

                    }
                });
            }
        });
    }

    /**
     * 搜索功能:在edittext中字符串發生變化的時候,自動提示相對應的poi信息,並顯示在對應的recycleview上
     */
    private void searchRange() {
        etSearchCityPoi.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                llMapAndPoiList.setVisibility(View.GONE);
                llSearchPlace.setVisibility(View.VISIBLE);

                //第二個參數傳入null或者“”代表在全國進行檢索,否則按照傳入的city進行檢索
                InputtipsQuery inputquery = new InputtipsQuery(s.toString(), "");
                inputquery.setCityLimit(true);//限制在當前城市
                Inputtips inputTips = new Inputtips(getContext(), inputquery);
                inputTips.setInputtipsListener(new Inputtips.InputtipsListener() {
                    @Override
                    public void onGetInputtips(List<Tip> list, int i) {

                        searchAdapter.setNewData(list);
                    }
                });
                inputTips.requestInputtipsAsyn();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });


    }

    /**
     * mapview下面的recycleview實例化和數據的顯示和對應的item點擊事件
     */
    private void initView() {
        rvBranchAddressChoose.setLayoutManager(new LinearLayoutManager(getContext()));
        poiListAdapter = new PoiListAdapter(R.layout.item_branch_poi_list);
        poiListAdapter.bindToRecyclerView(rvBranchAddressChoose);
        poiListAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                //防抖
                if (AntiShakeUtils.isInvalidClick(view)) {

                    return;
                }

                poiListAdapter.changeCheckedPositon(poiListAdapter.getItem(position).getTitle());
                rvBranchAddressChoose.scrollToPosition(0);


                double latlonPointLat = poiListAdapter.getItem(position).getLatLonPoint().getLatitude();
                double latlngPointLng = poiListAdapter.getItem(position).getLatLonPoint().getLongitude();
                LatLng latLngPoint = new LatLng(latlonPointLat, latlngPointLng);
                moveCameraUpdate(mapView, latLngPoint, 18f);

                eventMap = new WeakHashMap<>();

                eventMap.put("prov", poiListAdapter.getItem(position).getProvinceName());
                eventMap.put("city", poiListAdapter.getItem(position).getCityName());
                eventMap.put("county", poiListAdapter.getItem(position).getAdName());
                eventMap.put("detail", poiListAdapter.getItem(position).getSnippet());
                eventMap.put("lat", poiListAdapter.getItem(position).getLatLonPoint().getLatitude());
                eventMap.put("lng", poiListAdapter.getItem(position).getLatLonPoint().getLongitude());
            }
        });


        rvSearchByInputText.setLayoutManager(new LinearLayoutManager(getContext()));
        searchAdapter = new SearchPlaceListAdapter(R.layout.item_branch_poi_list);
        searchAdapter.bindToRecyclerView(rvSearchByInputText);
        searchAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                //防抖
                if (AntiShakeUtils.isInvalidClick(view)) {

                    return;
                }

                double selectLat;
                double selectLng;

                if (searchAdapter.getItem(position).getPoint() == null || "".equals(searchAdapter.getItem(position).getPoint())) {
                    SunsToastUtils.showCenterShortToast("獲取不到該點的經緯度,請重新選擇");
                    return;
                } else {
                    selectLat = searchAdapter.getItem(position).getPoint().getLatitude();
                    selectLng = searchAdapter.getItem(position).getPoint().getLongitude();

                    LatLng selectPoint = new LatLng(selectLat, selectLng);
                    moveCameraUpdate(mapView, selectPoint, 18f);
                    getCircumInfo(getContext(), selectLat, selectLng);
                    llMapAndPoiList.setVisibility(View.VISIBLE);
                    llSearchPlace.setVisibility(View.GONE);

                    eventMap = new WeakHashMap<>();
                    eventMap.put("detail", searchAdapter.getItem(position).getAddress());
                    eventMap.put("lat", searchAdapter.getItem(position).getPoint().getLatitude());
                    eventMap.put("lng", searchAdapter.getItem(position).getPoint().getLongitude());
                    getDetailByTip(getContext(), searchAdapter.getItem(position).getDistrict(), searchAdapter.getItem(position).getAdcode());
                    KeyboardUtils.hideSoftInput(MapDialog.this);
                }
            }

        });

    }

    /**
     * 根據tip返回的詳細地址獲取具體的省市縣名稱
     * @param context
     * @param address
     * @param adCode
     */
    private void getDetailByTip(Context context, String address, String adCode) {
        GeocodeSearch geocoderSearch = new GeocodeSearch(context);

        // name表示地址,第二個參數表示查詢城市,中文或者中文全拼,citycode、adcode
        GeocodeQuery query = new GeocodeQuery(address, adCode);

        geocoderSearch.getFromLocationNameAsyn(query);

        geocoderSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {

            }

            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                if (i == 1000) {
                    eventMap.put("prov", geocodeResult.getGeocodeAddressList().get(0).getProvince());
                    eventMap.put("city", geocodeResult.getGeocodeAddressList().get(0).getCity());
                    eventMap.put("county", geocodeResult.getGeocodeAddressList().get(0).getDistrict());

                }
            }
        });
    }

    /**
     * 點擊獲取到的聯想數據poi item時,地圖中心點藍點移動到對應的位置
     *
     * @param mv
     * @param ll
     * @param zoom
     */
    private void moveCameraUpdate(MapView mv, LatLng ll, Float zoom) {
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(ll, zoom);
        mv.getMap().animateCamera(cameraUpdate);
    }

    @Override
    protected void onDismiss() {
        super.onDismiss();
        mapView.onDestroy();
    }


    /**
     * 根據傳入的經緯度,獲取相對應的poi聯想數據
     *
     * @param message
     */
    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    public void onGetMessage(EventMessage message) {
        switch (message.getCode()) {
            case EventCode.BRANCH_ADDRESS_LOCATION_POI:

                EventBusUtils.removeSticky(message);
                break;
        }

    }

    /**
     * 根據經緯度獲取周邊的地址列表
     *
     * @param context
     * @param lat
     * @param lng
     */
    private void getCircumInfo(Context context, Double lat, Double lng) {
        PoiSearch.Query query = new PoiSearch.Query("", "", "");
        query.setPageSize(100);// 設置每頁返回多少條數據
        query.setPageNum(1);// 設置查詢頁碼

        PoiSearch poiSearch = new PoiSearch(context, query);

        poiSearch.setBound(new PoiSearch.SearchBound(new LatLonPoint(lat, lng), 1000));
        poiSearch.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() {
            @Override
            public void onPoiSearched(PoiResult poiResult, int i) {
                if (i != 1000) {
                    SunsToastUtils.showCenterShortToast("無法查詢周邊信息" + i);
                } else {
                    if (poiResult != null) {
                        poiListAdapter.setNewData(poiResult.getPois());
                    }
                }
            }

            @Override
            public void onPoiItemSearched(PoiItem poiItem, int i) {

            }
        });
        poiSearch.searchPOIAsyn();
    }

    private OnConfirmListener mListener = null;

    public MapDialog setOnConfirmListener(OnConfirmListener listener) {
        mListener = listener;
        return this;
    }

    public interface OnConfirmListener {
        void onConfirm(WeakHashMap map);
    }


    /**
     * 點擊確認帶參返回
     */
    private void clickEnsure() {
        tvEnsureCommitBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (AntiShakeUtils.isInvalidClick(v)) {
                    return;
                }
                dismiss();
                if (mListener != null) {
                    dismiss();
                    if (!eventMap.isEmpty()) {
                        mListener.onConfirm(eventMap);

                    }
                }
                KeyboardUtils.hideSoftInput(MapDialog.this);
            }
        });
    }
}

使用方法的話就跟之前的CenterPopupView一樣使用就好了,有啥不懂得,或者我代碼哪裏有問題,或者你覺得哪裏我還可以優化的,熱烈歡迎在評論區留言啊,謝謝您嘞。那麼,這期就到這,告辭!

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章