конечно можно сделать.
Я думаю, что самым простым для вашей ситуации, плюс вы можете легко расширить, является создание некоторых вспомогательных функций, которые заботятся о:
1) создать пустой экран 2) создать кнопку для экрана 3) создать текстовое представление для экрана и, наконец, 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: Расширение представления Создайте новый .java с именем «MyCoolScreen.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, поэтому ваш код активности очень чистый, и вы даже можете расширить функциональность View, не делая его уродливым.
Также обычной практикой является создание интерфейсов и прослушивателей для ваших представлений для связи с внешним миром, поэтому, например, мы можем сделать:
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.
Там могут быть ошибки, просто набрал код здесь, но я надеюсь, что это поможет вам!
person
rupps
schedule
14.05.2013