SwipeRefreshLayout在Android中填充父级

时间:2016-03-14 13:52:02

标签: android android-layout swiperefreshlayout

我尝试使用SwipeToRefreshLayout更新标记内的某些信息。虽然我使用android:layout_width="wrap_content"来保留内容大小,但由于某种原因,它总是填充父级,在信息内容下面留下了很大的空间。我做错了什么?

顺便说一句,如果我没有SwipeRefreshLayout,并且只使用ScrollView,那么该空格就不会出现。

这是我的XML代码:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/svMarker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/svMarkerInfo">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/llMarkerInfo">
        </LinearLayout>
    </ScrollView>

</android.support.v4.widget.SwipeRefreshLayout>

感谢您的回答!

我还留下了使用SwipeRefreshLayout显示的图像。标记信息后面有一张地图:

Image showing the marker info using the SwipeRefreshLayout

如果我不使用SwipeRefreshLayout,标记信息会以下一种方式显示,这在视觉上就是我要找的内容。但是我错过了SwipeToRefresh更新:

Image showing the marker info without using SwipeRefreshLayout

2 个答案:

答案 0 :(得分:0)

使用侦听器拖动地图时将禁用SwipeRefreshLayout,只有在向下滑动下半部分(即地图下方的布局)时才会进行刷新。要获取地图拖动事件,我们需要采取一些解决方法,因为没有Google的直接支持,此库MapStateListener已经完成了。只需将这三个类MapStateListener.javaTouchableMapFragment.javaTouchableWrapper.java粘贴到您的项目中即可。

这是一个有效的例子。

<强> MainActivity.java

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback
{
    private SwipeRefreshLayout swipeRefreshLayout;
    private View  secondHalf;
    private TouchableMapFragment mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.svMarker);
        secondHalf = findViewById(R.id.secondHalf);

        setUpMap();

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
        {
            @Override
            public void onRefresh()
            {
                // A thread to keep RefreshLayout busy for 5 seconds
                if(!swipeRefreshLayout.isRefreshing())
                    new LoadImagesTask().execute();
            }
        });
    }

    public void setUpMap()
    {
        try
        {
            if (mMap == null)
            {
                mMap = ((TouchableMapFragment) getSupportFragmentManager()
                        .findFragmentById(R.id.firstHalf));
                mMap.getMapAsync(this);

            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap)
    {
        new MapStateListener(googleMap, mMap, this)
        {
            @Override
            public void onMapTouched()
            {
                // Map touched
                swipeRefreshLayout.setEnabled(false);
            }

            @Override
            public void onMapReleased() {
                // Map released
                swipeRefreshLayout.setEnabled(true);
            }

            @Override
            public void onMapUnsettled() {
                // Map unsettled
            }

            @Override
            public void onMapSettled() {
                // Map settled
            }
        };
    }

    private class LoadImagesTask extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... voids)
        {
            try
            {
                for (int i = 1; i <= 5; i++)
                {
                    Thread.sleep(1000);
                }
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid)
        {
            super.onPostExecute(aVoid);
            swipeRefreshLayout.setRefreshing(false);
        }
    }
}

<强> main.xml中

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/svMarker"
                                              xmlns:android="http://schemas.android.com/apk/res/android"
                                              android:layout_width="match_parent"
                                              android:layout_height="match_parent"
    >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:weightSum="2">

        <fragment
            android:id="@+id/firstHalf"
            android:name="com.esealed.watermeterclient.TouchableMapFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            />

        <ScrollView
            android:id="@+id/secondHalf"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/colorAccent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

               <!-- Other views comes here -->

            </LinearLayout>
        </ScrollView>
    </LinearLayout>

</android.support.v4.widget.SwipeRefreshLayout>

答案 1 :(得分:0)

我能想到的唯一解决方案就是在动态上定义SwipeRefreshLayout大小。无需更改我的XML文件。

在我管理标记信息的MapActivity.class上,每当我显示新标记信息时,我都会调用下一个方法:

LinearLayout llMarkerInfo = (LinearLayout) findViewById(R.id.llMarkerInfo);
SwipeRefreshLayout svMarker = (SwipeRefreshLayout) findViewById(R.id.svMarker);

//First i register to the listener so I can get the measured size of the marker information's layout
ViewTreeObserver vto = llMarkerInfo.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override        
    public void onGlobalLayout() {

        //I get the measured width and height of the marker information's layout
        int width = llMarkerInfo.getMeasuredWidth();
        int height = llMarkerInfo.getMeasuredHeight();

        //Set that size to the SwipeToRefresh layout
        LinearLayout.LayoutParams svParams = new LinearLayout.LayoutParams(width, height);
        svMarker.setLayoutParams(svParams);

        //Unregister the listener so is not called many times
        if (Build.VERSION.SDK_INT < 16)
            llMarkerInfo.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        else
            llMarkerInfo.getViewTreeObserver().removeOnGlobalLayoutListener(this);
     }
});

这样,我就可以准确地将我的标记信息的布局大小定义为我的SwipeRefreshLayout

带有最终结果的图像(预期=现实): Image with the final result