2016-03-14 6 views
-1

Я пытаюсь использовать SwipeToRefreshLayout для обновления некоторой информации внутри маркера. Хотя я использую android:layout_width="wrap_content", чтобы сохранить размер контента, по какой-то причине он всегда заполняет родителя, оставляя огромное пространство ниже информационного содержимого. Что я делаю не так?SwipeRefreshLayout заполняет родителя в Android

Кстати, если у меня нет 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

+0

Вы не добавили никаких элементов внутри Linear Layout па? Попробуйте добавить TextView или что-то еще, чтобы он мог сделать некоторую высоту. – Neeraj

+0

Я упростил его. Будет добавлен образ, чтобы вы могли видеть, что у него внутри. Но, как я уже сказал, это прекрасно видно, если я заберу SwipeRefreshLayout –

+0

Не можете ли вы использовать вид перекоса вместо scrollview и Linear layout? так что вы можете установить адаптер для него, чтобы создать этот макет. – Neeraj

ответ

0

SwipeRefreshLayout будет отключена при перемещении карты с помощью слушателя и обновление будет иметь место только, если провести пальцем вниз на вторую половину (т.е. расположение ниже карта). Чтобы получить события перетаскивания карты, нам нужно сделать некоторое обходное решение, потому что прямой поддержки от Google нет, и эта библиотека MapStateListener сделала это. Просто вставьте эти три класса MapStateListener.java, TouchableMapFragment.java, TouchableWrapper.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> 
+0

спасибо. Проблема заключается в том, что если я прокручу вниз по карте, появится SwipeRefreshLayout, и это противоречит спецификации Google Design (https://www.google.com/design/spec/patterns/swipe-to-refresh .html # swipe-to-refresh-swipe-to-refresh) если вы уберете SwipeRefreshLayout, это в основном то, что я делаю в своем коде :) –

+0

@DiieBarcia 'SwipeRefreshLayout' должен работать только при перетаскивании второй половина ... не в первой половине (MAP), а обновление должно появиться сверху? –

+0

, но «значок загрузки» будет отображаться в верхней части экрана .. и если пользователь перевернет информацию о маркере, будет запутывать его, потому что «значок загрузки» не появится внутри информации маркера. –

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