2011-10-08 81 views
47

編輯:見我自己的答案,方便的解決方案Android的 - 多個可查看項目的水平滾動

重要賞金供清晰的方式來修改ViewPager滿足下面列出的場景。請不要提供Horizo​​ntalScrollView - 我需要完整的片段生命週期場景覆蓋

我需要實現的Fragments,其中一個項目是在中心和項目左/右部分或完全可見的看法基於橫向滾動。 ViewPager因爲它專注於每次顯示一個項目,所以不適合執行此任務。

爲了便於理解,下面是一個快速草圖,其中項目1,5和6位於可視區域之外。並且想要使這個可視數字可配置,例如在縱向視圖中,我將只顯示2個(或可能只是一個)項目。

我並不是想在屏幕上顯示3個項目,只要顯示中央項目,其他人可以裁剪。在小屏幕上可以有1箇中央項目,並且隨着屏幕長度增加(裁剪是OK)項目應顯示

我知道這看起來像一個畫廊,但再次項目不是簡單的圖像,但Fragments與每個片段中的垂直滾動列表

PS通過@Commonsware發現這個博客帖子list 3 different approaches。對於我的需要,我喜歡#3

enter image description here

+2

此鏈接將幫助您[Horizo​​ntalListView(http://www.dev-smart.com/archives/34) – surendra

+0

我需要有片段的水平滾動每個都有一個垂直ListView – Bostone

+0

我有一個非常相似的需求。我一直在使用Gallery,直到我開始在畫廊項目視圖中添加一個ListView後,開始在整個場所泄漏對象。目前正在考慮修復Gallery,因爲它比試圖修復ViewPager更容易。 –

回答

24

這一個有令人驚訝的簡單答案,我甚至不知道爲什麼不馬上公佈。爲了得到確切的效果,我需要做的只是覆蓋PagerAdapter#getPageWidth方法。默認情況下,它返回1,但如果你將它設置爲0.5,你會得到2頁,0.33會給你3等等。根據分頁器項目之間的分隔符的寬度,你可能需要稍微減少值。

請參見下面的代碼片段:

@Override 
    public float getPageWidth(final int position) { 
     // this will have 3 pages in a single view 
     return 0.32f; 
    } 
0

我能想到的兩種方法可能實現這一點。

  1. 作者:ViewSwitcher。 這是一個很好的YouTube video顯示它如何與onGestureListener工作。但是,我不確定這是否可以與您的圖片顯示的多個視圖一起使用。可以使用HorizontalScrollView作爲替代方案。 但是,如果您在另一個ScrollView中有一個ScrollView,則這通常會導致問題,但它可能值得一試!

讓我知道怎麼回事, 祝你好運!

+0

請閱讀賞金筆記 – Bostone

0

Check out this blog post如何編寫自定義的水平滾動視圖來實現類似的東西。該示例一次只能顯示一個屏幕,但您應該可以根據需要輕鬆修改它。

+0

我已經實現了基於ViewPager的功能,該功能在當時只有一個屏幕。我特別要求在賞金中使用多個/部分視圖 – Bostone

+0

正確的是,該示例中的代碼不會完全按照您想要的那樣進行,但它是一個很好的開始。在這個例子中,內部視圖與外部視圖(水平滾動視圖)具有相同的寬度,所以很自然地,一次只能看到其中的一個。你可以調整代碼,使你的內部視圖比外部滾動視圖窄。這將允許它們中的多個同時可見。如果你這樣做,你還需要調整「scrollTo」值,以便在發生「捕捉」時中間視圖正確居中。 – Joel

+0

我正在看ViewPager做同樣的事情。我不想去Horizo​​ntalScrollView路線,因爲那樣我就會丟失很多ViewPager相關的碎片功能 – Bostone

2

一旦我寫了類似的模板。在我的例子中,我可以上下左右滾動按鈕。您可以修改它以滿足您的要求。在我的例子,我有4次安排是這樣的:


它看起來像這樣。在圖像I從視圖向右滾動來查看2:

Android View Scrolling

的代碼由此XML的:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
     <LinearLayout 
     android:layout_height="350sp" 
     android:layout_width="320sp"> 
     <LinearLayout 
      android:id="@+id/viewContainer" 
      android:background="#CCCCCC" 
      android:layout_width="640sp" 
      android:layout_height="700sp"> 
     </LinearLayout> 
    </LinearLayout> 
     <TableLayout 
      android:id="@+id/tableLayout" 
      android:layout_width="320sp" 
      android:layout_height="fill_parent" 
      android:stretchColumns="1" 
      android:gravity="bottom" 
      android:layout_alignParentBottom="true"> 
      <TableRow 
      android:background="#333333" 
      android:gravity="bottom">  
      <Button 
       android:id="@+id/btnUp" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:text="Lift U" 
       /> 
      <Button 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:visibility="invisible" 
      /> 
      <Button 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:visibility="invisible" 
      /> 
      <Button 
       android:id="@+id/btnScreenUp" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:layout_gravity="right" 
       android:text="Scrn U" 
       /> 
      </TableRow> 
      <TableRow 
       android:background="#444444" 
       android:layout_gravity="right"> 
       <Button 
       android:id="@+id/btnDown" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:text="Lift D" 
       /> 
       <Button 
       android:id="@+id/btnEnter" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:text="Enter" 
       /> 
       <Button 
       android:id="@+id/btnScreenLeft" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:layout_gravity="right" 
       android:text="Scrn L" 
       /> 
       <Button 
       android:id="@+id/btnScreenDown" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:layout_gravity="right" 
       android:text="Scrn D" 
       /> 
       <Button 
       android:id="@+id/btnScreenRight" 
       android:layout_width="60sp" 
       android:layout_height="50sp" 
       android:layout_gravity="right" 
       android:text="Scrn R" 
       /> 
      </TableRow> 
    </TableLayout> 
</FrameLayout> 

和此Java代碼:

import android.app.Activity; 
import android.os.Bundle; 
import android.util.DisplayMetrics; 
import android.view.Gravity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.Window; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class ViewSwitcherTest extends Activity { 

    private TextView view1, view2, view3, view4; 
    private Button btnUp, btnEnter, btnDown, btnScreenDown, btnScreenUp, btnScreenLeft, btnScreenRight; 
    private LinearLayout viewContainer; 
// private TableLayout tableLayout; 
    private LinearLayout.LayoutParams layoutParams; 
    private DisplayMetrics metrics = new DisplayMetrics(); 
    private int top = 0, left = 0; 
    private float density = 1.0f; 
// private ViewSwitcher switcher; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindowManager().getDefaultDisplay().getMetrics(metrics); 
     density = metrics.density; 
     setContentView(R.layout.main); 
//  Buttons 
     btnEnter = (Button)findViewById(R.id.btnEnter); 
     btnUp = (Button)findViewById(R.id.btnUp); 
     btnDown = (Button)findViewById(R.id.btnDown); 
     btnScreenDown = (Button)findViewById(R.id.btnScreenDown); 
     btnScreenUp = (Button)findViewById(R.id.btnScreenUp); 
     btnScreenLeft = (Button)findViewById(R.id.btnScreenLeft); 
     btnScreenRight = (Button)findViewById(R.id.btnScreenRight); 
//  -------- 
//  tableLayout = (TableLayout)findViewById(R.id.tableLayout); 
     view1 = new TextView(this); 
     view1.setBackgroundResource(R.drawable.view1); 
     view1.setHeight((int)(350*density)); 
     view1.setWidth((int)(320*density)); 
     view1.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); 
     layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(left, top, 0, 0); 
     viewContainer = (LinearLayout)findViewById(R.id.viewContainer); 
     viewContainer.addView(view1, layoutParams); 
     //Add 2nd view 
     view2 = new TextView(this); 
     view2.setBackgroundResource(R.drawable.view2); 
     view2.setHeight((int)(350*density)); 
     view2.setWidth((int)(320*density)); 
     view2.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); 
     layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(left, top, 0, 0); 
     viewContainer.addView(view2, layoutParams); 
     //Add 3rd view 
     view3 = new TextView(this); 
     view3.setBackgroundResource(R.drawable.view3); 
     view3.setHeight((int)(350*density)); 
     view3.setWidth((int)(320*density)); 
     view3.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); 
     top += 350*density; 
     left += 640*density*(-1); 
     layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(left, top, 0, 0); 
     viewContainer.addView(view3, layoutParams);  
     //add 4th view 
     view4 = new TextView(this); 
     view4.setBackgroundResource(R.drawable.view4); 
     view4.setHeight((int)(350*density)); 
     view4.setWidth((int)(320*density)); 
     view4.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL); 
     top += 0; 
     left += 640*density; 
     layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); 
     layoutParams.setMargins(left, top, 0, 0); 
     viewContainer.addView(view4, layoutParams);  
     btnEnter.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // Quit the application for now 
       finish(); 
      } 
     }); 
     btnScreenLeft.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       viewContainer.scrollBy(-10,0); 
      } 
     }); 
     btnScreenRight.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       viewContainer.scrollBy(10,0); 
      } 
     }); 
     btnScreenUp.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       viewContainer.scrollBy(0,-10); 
      } 
     }); 
     btnScreenDown.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       viewContainer.scrollBy(0,10); 
      } 
     }); 
//  view1.setOnKeyListener(new OnKeyListener() {    
//   @Override 
//   public boolean onKey(View v, int keyCode, KeyEvent event) { 
//    if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) 
//     viewContainer.scrollBy(0,10); 
//    return true; 
//   } 
//  }); 
    } 
} 

每個屏幕上的大數字都是帶有這些數字的黑色背景圖像。 (我沒有在這裏發佈,因爲你可能會修改代碼)。

+0

不行,不能走這條路線。我有更復雜的設置,我使用ViewPager和FragmentStatePagerAdapter來處理碎片生命週期。在這一點上,我幾乎設置了修改ViewPager的想法,並尋找哪些部分需要修改/擴展的提示 – Bostone

0

如果要擴展ViewPager,只需重寫draw方法和setOffscreenPageLimit(int limit)即可。但是,如果你的碎片本身有點複雜,我推薦使用FragmentPageAdapter

您可以查看源代碼here或者如果你想檢查一個在支持包,你可以做到這一點here

+0

我正在使用FragmentStatePagerAdapter,但需要照顧一個單一的片段,我需要重組的方式列表在屏幕上放置多個片段。我知道代碼的來源,謝謝 – Bostone

+0

如果除了主函數之外的代碼片段不需要處於活動狀態,只需使用縮放縮小中央代碼片段,並在代表組件/片段的任一側添加圖片即可。一次製作圖像,然後在您滾動該區域時繪製它們。 –

+0

它的確如此。特別是如果你在平板電腦和側片完全可見 – Bostone

1

我們正在做一件幾乎完全如您所描述的使用GalleryFragments以及一個擴展了BaseAdapter的圖庫適配器。我會建議去一個畫廊來實現你的目標(我們也使用ViewPager作爲我們不需要看到其他片段的視圖)。