我有興趣使用用戶定義數量的相同視圖填充屏幕/活動。每個視圖將具有完全相同的佈局:幾個TextViews和幾個按鈕。問題是每個按鈕都將控制每個TextView將顯示的內容。動態添加多個視圖和類到當前視圖
我想實現它的方式是有一個XML和一個Java類。然後取決於用戶輸入的數字,用許多相同的視圖填充屏幕(使用for循環)。問題是,它可以做到嗎?怎麼樣?我是否以正確的方式思考它?
請幫助任何輸入或想法,代碼示例將很好。
我有興趣使用用戶定義數量的相同視圖填充屏幕/活動。每個視圖將具有完全相同的佈局:幾個TextViews和幾個按鈕。問題是每個按鈕都將控制每個TextView將顯示的內容。動態添加多個視圖和類到當前視圖
我想實現它的方式是有一個XML和一個Java類。然後取決於用戶輸入的數字,用許多相同的視圖填充屏幕(使用for循環)。問題是,它可以做到嗎?怎麼樣?我是否以正確的方式思考它?
請幫助任何輸入或想法,代碼示例將很好。
是可以做到的。
我認爲最簡單的爲您的情況,再加上那麼你就可以輕鬆地擴展,是創建照顧一些輔助功能:
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.
有可能是錯誤,只需在此鍵入代碼,但我希望它能幫助你!
我沒有測試過這段代碼,但看起來沒錯。正如我所想的那樣。我遺漏的東西,你的帖子提出,解決方案的思想是爲每個創建的元素生成唯一的ID。我將添加到您的代碼'.setId(i);'爲每個添加的元素。 :-)它遲到了,我明天會測試它,並會回覆。 -Cheers – KingsInnerSoul 2013-05-14 04:50:35
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
它的作用就像一個魅力(在重載修改你的代碼以適應我所期望的外觀之後)。現在我遇到了LinearLayout中id和標籤以及元素順序的問題。無法找到在onClick按鈕上調用TextViews的正確方法。 – KingsInnerSoul 2013-05-15 05:28:17
Add and Remove Views in Android Dynamically?
這將有助於您最...
我已經閱讀過此文件。它不是我要找的。我正在尋找動態添加多個視圖(源自一個視圖),並能夠獨立控制每個視圖的事件。諸如爲每個單獨視圖更改TextViews和ImageViews等事件。 – KingsInnerSoul 2013-05-14 04:39:03
我還沒有試過。我一直在閱讀最好和最有效的方式來做到這一點。我看過片段,充氣器和列表視圖。但我正在尋找使它對每個單獨添加視圖上的按鈕做出反應。我無法找到有關文件的解釋。 – KingsInnerSoul 2013-05-14 04:14:49
你應該刪除你的問題。你會被打上標籤,並像地獄一樣低調。 – Siddharth 2013-05-14 04:15:44
多數民衆贊成在另一件事,我一直在尋找。如何刪除問題? – KingsInnerSoul 2013-05-14 04:31:44