I am trying to add Views to a custom ViewGroup. The ViewGroup gets drawn, but no Views that were added to it are visible. LineView's (which extends a View) onDraw() method does not get called. What am I doing wrong?
public class TestActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ShapeView shapeView = new ShapeView(this);
shapeView.setBackgroundColor(Color.RED);
drawContainer = (RelativeLayout)findViewById(R.id.draw_container);
drawContainer.addView(shapeView);
}
}
public class ShapeView extends ViewGroup {
private LineView mLineView;
public ShapeView (Context context) {
super(context);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(200, 200);
this.setLayoutParams(p);
mLineView = new LineView(context);
this.addView(mLineView);
}
}
I maybe wrong but should you not be adding the shapeView to your layout "main"? What is drawContainer? I can't see it being instantiated and not in the docs. I assume main contains a relative/linear layout.
Access it by:
RelativeLayout rel = (RelativeLayout) findViewById(R.id.container);
(where the id is changed to match your id)
then:
rel.addView(shapeView);
Related
I have created an external class, NotesView, which extends View for implementation in my MainActivity.
This View requires information passed from the MainActivity, so its constructor takes an ArrayList of Note objects.
public class NotesView extends View {
private ArrayList<Note> notes = new ArrayList<>();
public NotesView(Context context, ArrayList<Note> notes) {
super(context);
this.notes = notes;
}
In my MainActivity, I used the following code to display this view: (Trying to add a CustomView in the Design tab of the layout does not work as I cannot supply the ArrayList parameter)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notesView = new NotesView(this, noteList);
setContentView(notesView);
}
Unfortunately, I am now not able to add any objects at all through the Design view of the layout, I assume this is because I have used setContentView. I do not wish to add all my components programmatically, is there a way around this?
Calling setContentView replaces the whole view for your layout. That means if you call setContentView twice, whatever was added to the screen from the first call is overridden and no longer accessible.
There are multiple answers to your question, here is a pragmatic one:
What is inside R.layout.activity_main? Let's assume there is a FrameLayout / LinearLayout / RelativeLayout with id root
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup rootView = (ViewGroup) findViewById(R.id.root);
notesView = new NotesView(this, noteList);
rootView.addView(notesView);
}
Another choice, you could also take your custom view to have a setter if you wish:
public class NotesView extends View {
private final List<Note> notes = new ArrayList<>();
public NotesView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void replaceNotes(List<Note> notes) {
this.notes.clear();
this.notes.addAll(notes);
}
Then you can add this view in your XML file (R.layout.activity_main) and call the setter method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NotesView notesView = (NotesView) findViewById(R.id.notes);
notesView.replaceNotes(noteList);
}
You can add a setter function to your NotesView class:
public class NotesView extends View {
private ArrayList<Note> notes;
public NotesView(Context context) {
super(context);
}
public void setNotes(ArrayList<Note> notes) {
this.notes = notes;
}
}
And then set it in the main activity:
NotesView notesView = (NotesView) findViewById(R.id.yourNotesView);
notesView.setNotes(noteList);
By the way I recommend Butterknife to cast views in your layout without the verbose findViewByIds, declarations, onXListeners, etc.
This is what i am trying to do, this my main class file
private View TicTacStart;
//onCreate
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
TicTacStart = new Game(this);
//reference to base layout..
LinearLayout baseView = (LinearLayout)findViewById(R.id.baseView);
//I cant INFLATE THE VIEW SINCE I AM NOT USING XML AND RATHER USING ANOTHER CLASS GAME WHICH EXTENDS VIEW
LayoutInflater vi = (LayoutInflater)thisActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View thisScreensView = vi.inflate(TicTacStart, null);
//add the view to the base view...
baseView.addView(thisScreensView);
}
This is game class
public class Game extends View {
private Cell[][] singlesquare = null;
int x = 3;
int y = 3;
private int l;
private int a;
private boolean whatdrawn = false;
private int playerwin = 3;
private Paint caneta;
Data Data MORE classes
}
so basically what I want to do is add Game view class into baseview in my main class file. Is there someway i can make this work as i don't want to use xml's now.
Yuu can directly add GameView into baseview for ex:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
TicTacStart = new Game(this);
//reference to base layout..
LinearLayout baseView = (LinearLayout)findViewById(R.id.baseView);
baseView.addView(TicTacStart );
}
I have a custom Relative Layout and added a button to it
RelativeLayout rel_layout = new RelativeLayout(mcontext);
RelativeLayout.LayoutParams rel_param = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
rel.setLayoutParams(rel_param);
Button b = new Button(mcontext);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
b.setLayoutParams(params);
b.setText("Test");
rel_layout.addView(b);
Now, I want this Relative layout to be added to a View. My View Class looks like this is
public class CustomView extends View {
Context mcontext;
public CustomView(Context context) {
super(context);
this.mcontext = context;
}
}
and in the Main Activity I am calling this view in my setConentView()
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CustomView(this));
}
}
So now on the Screen I should have the relative layout with the button in it. I should not use any XMl's.
I need help in how to add the dynamic relative created to be added to my CustomView class
Hope I have explained my problem clearly.
// try this
custom_view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relCustomView"
android:background="#android:color/darker_gray"
android:padding="5dp">
</RelativeLayout>
public class CustomView extends View{
private Context context;
public CustomView(Context context) {
super(context);
this.context=context;
}
public View getCustomView(){
View v = LayoutInflater.from(context).inflate(R.layout.custom_view,null,false);
RelativeLayout relCustomView = (RelativeLayout) v.findViewById(R.id.relCustomView);
Button b = new Button(context);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
b.setLayoutParams(params);
b.setText("Test");
relCustomView.addView(b);
return v;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CustomView(this).getCustomView());
}
You are not supposed to do that. RelativeLayout is a ViewGroup. ViewGroup is a View that can hold one or more Views as children. You should implement your own ViewGroup instead of View.
You can find a tutorial for implementing custom ViewGroup here:
https://developer.android.com/reference/android/view/ViewGroup.html
Also, I'd like to suggest that you might actually want to place RelativeLayout directly on your Activity and place some customized widgets on top of it along with the button you mentioned.
Your custom view has to extend a ViewGroup, not a View.
I have a custom view extending RelativeLayout (could be any other viewgroup). In this view I have several framelayouts added with addView(). No XML exists for this view! The view constructer adds everything from code.
I want to use this custom view as any other content view for an activity.
I have this fragment activity:
MyView myview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myview = new MyView(this);
myview.getSomeContainedFrameLayoutOfView().setId(12345);
setContentView(myview);
}
Then I do this in onResume
#Override
protected void onResume() {
super.onResume();
View u = findViewById(12345); // test, returns null
u = myview.findViewById(12345); // test, also null
SomeFragment f = new SomeFragment();
FragmentManager m = getSupportFragmentManager();
FragmentTransaction ft = m.beginTransaction();
ft.replace(12345, f); // ofcourse error (no view found for id)
ft.commit();
}
Why is findViewById null? If I change setContentView() line to
setContentView(R.layout.myframelayouts);
Everything works. So somehow I suspect
setId(12345)
does something different from:
android:id="#+id/someid"
What am I missing?
Is the view returned by getSomeContainedFrameLayoutOfView() actually contained in the RelativeLayout? That is, somewhere in MyView have you called AddView(theTargetView)?
If the target view is simply a member of MyView, then the RelativeLayout, which implements findViewById unless you override it, doesn't know about the target view.
I have something like this:
public class MojLayout extends LinearLayout {
private FrameLayout lijeviFrame;
private FrameLayout glavniFrame;
private int layoutWidth;
private int panel;
private boolean glavniFrameFullScreen = false;
public MojLayout(final Context context, final float leftWeight) {
super(context);
lijeviFrame = new FrameLayout(context);
glavniFrame = new FrameLayout(context);
post(new Runnable() {
#Override
public void run() {
layoutWidth = getWidth();
panel = (int) (layoutWidth / leftWeight);
init(context);
}
});
}
private void init(Context context) {
lijeviFrame.setId(R.id.lijeviFrame); //defined in /res/values/ids.xml
glavniFrame.setId(R.id.glavniFrame);
LinearLayout container = new LinearLayout(context);
container.setOrientation(HORIZONTAL);
....
container.addView(lijeviFrame);
container.addView(glavniFrame);
addView(container);
}
In onCreate() method I tried myView.findViewbyId(R.id.lijeviFrame) -> null, without myView, same.
I don't get it
I have the following class
public class GameActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View gameView = new GameView(this);
setContentView(gameView);
}
}
and now I'd like to add a Button to my class GameView.
public GameView(Context context) {
super(context);
// Code ...
}
I need this button during my game, so it should be alywas in front of all the other canvas' I'm drawing. How can I do that?
Do you want to create a new button?
Button b = new Button(context);
b.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
gameView.addView(b);
Use ViewGroup as GameView parent insted of simple View
ViewGroup gameView = new GameView(this);
public class GameView extends ViewGroup { //...
View gameView = new GameView(this);
replace the above line by below line::
View gameView = new GameView(this).createView();
and now in the Game view createview with button and etc.
public class GameView extends View {
private Activity _activity;
public GameView (Activity _activity) {
super(_activity);
// TODO Auto-generated constructor stub
this._activity = _activity;
}
public View createView(){
LinearLayout l = new LinearLayout(_activity);
l.setOrientation(LinearLayout.VERTICAL);
Button btn = new Button(_activity);
btn.setId(1);
btn.setText("btn"+(i+1));
l.addView(btn);
return l;
}
}
try this working code:::