2013-05-14 115 views
0

我有興趣使用用戶定義數量的相同視圖填充屏幕/活動。每個視圖將具有完全相同的佈局:幾個TextViews和幾個按鈕。問題是每個按鈕都將控制每個TextView將顯示的內容。動態添加多個視圖和類到當前視圖

我想實現它的方式是有一個XML和一個Java類。然後取決於用戶輸入的數字,用許多相同的視圖填充屏幕(使用for循環)。問題是,它可以做到嗎?怎麼樣?我是否以正確的方式思考它?

請幫助任何輸入或想法,代碼示例將很好。

+0

我還沒有試過。我一直在閱讀最好和最有效的方式來做到這一點。我看過片段,充氣器和列表視圖。但我正在尋找使它對每個單獨添加視圖上的按鈕做出反應。我無法找到有關文件的解釋。 – KingsInnerSoul 2013-05-14 04:14:49

+0

你應該刪除你的問題。你會被打上標籤,並像地獄一樣低調。 – Siddharth 2013-05-14 04:15:44

+0

多數民衆贊成在另一件事,我一直在尋找。如何刪除問題? – KingsInnerSoul 2013-05-14 04:31:44

回答

1
當然

是可以做到的。

我認爲最簡單的爲您的情況,再加上那麼你就可以輕鬆地擴展,是創建照顧一些輔助功能:

1創建一個空的屏幕 2)屏幕 創建一個按鈕) 3)屏幕 創建一個TextView終於 4)創建屏幕,並填充它

你必須決定正確的根元素爲您的看法,取決於孩子機務佈局需要。爲了簡單起見,讓我們選擇一個LinearLayout,但是對於RelativeLayout或TableLayout,這個例子是一樣的,它只是改變了當你添加元素時,你必須使用額外的參數來正確放置它們。

請注意,創建空自定義視圖的函數返回ViewGroup(「所有佈局都來自」)。這樣,您總是使用ViewGroups,只需在createCustomView中定義一次屏幕布局類型即可。所以,你可以改變屏幕的類型就在那裏,和代碼的其餘部分將工作...

這裏是你的靈感一些代碼:

private ViewGroup createCustomView(Context context) { 

    LinearLayout myCoolNewView=new LinearLayout(context); // or RelativeLayout, etc.. 
    return myCoolNewView; 
} 

private Button createButton(Context context, String buttonText) { 
    Button newButton=new Button(context); 
    newButton.setText(buttonText); 
    return newButton; 
} 

private TextView createText(Context context, String initialText) { 
    TextView newText=new TextView(context); 
    newText.setText(buttonText); 
    return newText; 
} 

private ViewGroup createScreen(Context context, int numberOfButtons, int numberOfTextfields) { 

    ViewGroup newScreen=createCustomView(context); 
    TextView[] textViews=new TextView[numberOfTextFields]; 

    for (int i=0; i<numberOfTextfields; i++) { 
      textViews[i]=createText(context, "hi i am text "+i); 
      newScreen.addView(textViews[i]); // you ideally provide here layoutparams to properly place your buttons 

    } 
    for (int j=0; i<numberOfButtons; j++) { 
      Button button=createButton(context, "hi i am button "+j); 
      button.setOnClickListener(new OnClickListener() { 
       public void onClick (View clickedView) { 
        // here you have a button keypress and you know all the textviews 
        textView[i%j].setText("hey you pressed me"); 
       } 
      }); 
      newScreen.addView(button); 
    } 
    return newScreen; 
} 

所以現在你可以:

ViewGroup screen1=createScreen(context, 10, 10); 
ViewGroup screen2=createScreen(context, 5, 3); 
ViewGroup screen3=createScreen(context, 2, 5); 

和屏幕添加到父佈局,到ViewFlipper,到ViewSwitcher,等...這樣的:

ViewGroup parentLayoutOfAllScreens=findViewById(R.id.root_of_screens); 
parentLayoutOfAllScreens.addView(screen1); 
parentLayoutOfAllScreens.addView(screen2); 
parentLayoutOfAllScreens.addView(screen3); 

在XML中,您只需創建根佈局,並將其命名爲root_of_screens ...

好的編碼!我想在上面的代碼中會出現一些錯誤,只需在這裏輸入它,但我希望你能明白並調整它以適應你的需求!

編輯:v2.0:擴展視圖 創建一個名爲「MyCoolScreen」的新.java。Java的」或任何名義,在您的活動(爲簡單起見)相同的文件夾:

package ........ 
public class MyCoolScreen extends LinearLayout { 

    /** Now every view holds its own buttons, and they are private, it's good for encapsulating */ 
    private TextView[] mTextViews; // <-- as a convention, members should start with "m" 
    private Button[] mButtons; 
    private UserPressedButtons mUserPressedButtonsListener; // See below 

    /** The following constructors must always be present for a custom view, and must always call super */ 
    public MyCoolScreen(Context context) { 
     // This is the constructor you will use when creating your view programmatically 
     super(context); 
    } 

    public MyCoolScreen(Context context, AttributeSet attrs) { 

     // This is the constructor Android calls when you include your custom view in an XML 
     // You can do this too!! 
     // The ATTRS will then include your numberofbuttons and numberoftextfields from the XML 
     // this is beyond the example, but read about it, it's interesting 

     super(context, attrs); // this MUST ALWAYS be here for custom views, or they will not work. 
           // it tells the parent view to continue the construction. 
    } 

    public MyCoolScreen(Context context, AttributeSet attrs, int defStyle) { 
     // Another constructor Android calls from the XML 
     super(context, attrs, defStyle); 
    } 


    /** We create an "init" method to initialize this view from outside */ 
    public void init(int numberOfTextViews, int numberOfButtons) { 
     createScreen(numberOfTextViews, numberOfButtons); 
    } 


    /** This is the same */ 
    private Button createButton(Context context, String buttonText) { 
     Button newButton=new Button(context); 
     newButton.setText(buttonText); 
     return newButton; 
    } 

    /** This is the same */ 
    private TextView createText(Context context, String initialText) { 
     TextView newText=new TextView(context); 
     newText.setText(buttonText); 
     return newText; 
    } 

    /** We tweak this function so it doesnt return a view, but rather fills up this one :) */ 

    private void createScreen(int numberOfButtons, int numberOfTextfields) { 

     ViewGroup newScreen=this; // It's this view the one we gonna fill up! 
     mTextViews=new TextView[numberOfTextfields]; 
     mButtons=new Button[numberOfButtons]; 
     Context context=getContext(); // Views always know their context after constructed 

     for (int i=0; i<numberOfTextfields; i++) { 
       mTextViews[i]=createText(context, "hi i am text "+i); 
       newScreen.addView(textViews[i]); // you ideally provide here layoutparams to properly place your buttons 
     } 

     for (int j=0; i<numberOfButtons; j++) { 
       Button button=createButton(context, "hi i am button "+j); 
       button.setId(j); 
       button.setOnClickListener(new OnClickListener() { 
        public void onClick (View clickedView) { 
         // here you have a button keypress and you know all the textviews 
         if (mUserPressedButtonsListener!=null) mUserPressedButtonsListener.OnButtonPressed(j); 
         textView[i%j].setText("hey you pressed me"); 
        } 
       }); 
       mButtons[j]=button; 
       newScreen.addView(button); 
     } 
    } 

    public interface UserPressedButtons { 
     public void OnButtonPressed(int buttonNumber); 
    } 

    public void setUserPressedButtonsListener (UserPressedButtons listener) { 
     mUserPressedButtonsListener=listener; 
    } 
} 

好了,所以現在要利用這一點,在你的活動,你可以這樣做:

import ....... .MyCoolScreen; 
    import ....... .MyCoolScreen.UserPressedButtons; 

    . 
    . 
    . 

    MyCoolScreen screen1=new MyCoolScreen(context); 
    screen1.init(5,5); // initializes the screen. 

    myRootLayout.addView(screen1); 

什麼很酷關於這一點,現在功能被完全封裝在你的自定義視圖中,並且它駐留在另一個.java中,所以你的活動代碼非常乾淨,甚至可以擴展視圖功能而不會使它變得更難看。爲您的視圖創建接口和偵聽器的常見做法與外界溝通,因此,例如,我們可以這樣做:

 screen1.setUserPressedButtonsListener(new MyCoolScreen.UserPressedButtons() { 
     @Override 
     public void OnButtonPressed (int number) { 
       // you know the user pressed button "number", and you can do stuff about it without 
       // having to include it inside the MyCoolScreen class. Of course in your example you 
       // don't need this at the moment, because the View will modify its textfield, but suppose 
       // one of the buttons is "rocket launch" , that is something you will handle at the activity level, ie. 

       if (number==ROCKET_LAUNCH) RocketLauncher.setTarget(10,10).launch(); // Your MyCoolScreen doesnt know how to launch rockets, but your activity maybe yes... 

     } 
    }); 

你可以做各種很酷的事情與你的新的自定義視圖。例如,你可以定義:

 @Override 
    public void OnDraw(Canvas c) { 
      c.drawEllipse ... 
      c.drawRectangle .... 
    } 

而且你可以畫出圓,線,等等...在你的文本框&按鈕:)對於這個工作,你必須把

setWillNotDraw(false) on the constructor. 

有可能是錯誤,只需在此鍵入代碼,但我希望它能幫助你!

+0

我沒有測試過這段代碼,但看起來沒錯。正如我所想的那樣。我遺漏的東西,你的帖子提出,解決方案的思想是爲每個創建的元素生成唯一的ID。我將添加到您的代碼'.setId(i);'爲每個添加的元素。 :-)它遲到了,我明天會測試它,並會回覆。 -Cheers – KingsInnerSoul 2013-05-14 04:50:35

+0

noprob :)但是現在你知道setId了,讓我告訴你關於setTag()的信息。這是老表哥,這樣你可以分配任何一個按鈕,而不僅僅是一個ID。你可以這樣做:view.setTag(「my button」),或view.setTag(new String [] {「button1」,「screen2」})或甚至view.setTag(new MyStuffInfo(a,b,c,d ,e)))....然後做view.getTag()來獲取它:) – rupps 2013-05-14 04:54:43

+0

它的作用就像一個魅力(在重載修改你的代碼以適應我所期望的外觀之後)。現在我遇到了LinearLayout中id和標籤以及元素順序的問題。無法找到在onClick按鈕上調用TextViews的正確方法。 – KingsInnerSoul 2013-05-15 05:28:17

0
+0

我已經閱讀過此文件。它不是我要找的。我正在尋找動態添加多個視圖(源自一個視圖),並能夠獨立控制每個視圖的事件。諸如爲每個單獨視圖更改TextViews和ImageViews等事件。 – KingsInnerSoul 2013-05-14 04:39:03