FrameLayouts not shown when used with Linear Layout - android

I would like to test out using fragment manager to replace fragments dynamically. In the main layout, under the parent liner layout, I have 3 layouts, one child linear layout and 2 child frame layouts. The idea is to use a button in the first child linear layout to swap fragments in the 3rd frame layouts.
The issue I am seeing: when the application is loaded, only the child linear layout shows up on the screen; the fragments and their frame layout container is not visible. Can someone tell whether I am doing anything wrong here? There are no particular errors in the LogCat...
I tried to tweak the weight parameter for child layouts to resolve this issue, but without too much success.
Thanks a lot in advance.
Here are the activities classes:
[MainActivity.java]
package com.jiao.android.todolist;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MainActivity extends Activity implements NewItemFragment.OnNewItemAddedListener {
private ArrayAdapter<String> aa;
private ArrayList<String> todoItems;
private ArrayAdapter<String> aa2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get reference to the Fragments
FragmentManager fm = getFragmentManager();
ToDoListFragment todoListFragment = (ToDoListFragment)fm.findFragmentById(R.id.list_container);
//The codes below shows how to load fragments dynamically through Fragment Manager transaction
//into the predefined frame container in the layout xml
if(todoListFragment == null)
{
todoListFragment = new ToDoListFragment();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.item_container, new NewItemFragment());
ft.add(R.id.list_container, todoListFragment);
ft.commit();
}
//Create the ArrayList of to do items
todoItems = new ArrayList<String>();
//Create the ArrayAdapter to bind the array to the List View
aa = new ArrayAdapter<String>(this,R.layout.todolist_item,todoItems);
//Bind the Array Adapter to the List View
todoListFragment.setListAdapter(aa);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onNewItemAdded(String newItem){
todoItems.add(newItem);
aa.notifyDataSetChanged();
}
public void onSwapButtonClicked (View view)
{
//Get reference to the Fragments
FragmentManager fm2 = getFragmentManager();
ToDoListPlainFragment todoListFragment2 = new ToDoListPlainFragment();
//The codes below shows how to load fragments dynamically through Fragment Manager transaction
FragmentTransaction ft2 = fm2.beginTransaction();
String myNewFragmentTag = null;
ft2.replace(R.id.list_container, todoListFragment2,myNewFragmentTag);
ft2.commit();
//Create the ArrayAdapter to bind the array to the List View
aa2 = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,todoItems);
//Bind the Array Adapter to the List View
todoListFragment2.setListAdapter(aa2);
}
}
[NewItemFragment.java]
package com.jiao.android.todolist;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
public class NewItemFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.new_item_fragment,container,false);
final EditText myEditText = (EditText)view.findViewById(R.id.myEditText);
//this is how an editText can respond to DPAD_CENTER
//or the enter key
myEditText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(event.getAction()==KeyEvent.ACTION_DOWN)
if((keyCode == KeyEvent.KEYCODE_DPAD_CENTER)||
(keyCode == KeyEvent.KEYCODE_ENTER))
{
String newItem = myEditText.getText().toString();
onNewItemAddedListener.onNewItemAdded(newItem);
myEditText.setText("");
return true;
}
return false;
}
});
return view;
}
public interface OnNewItemAddedListener {
public void onNewItemAdded(String newItem);
}
private OnNewItemAddedListener onNewItemAddedListener;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
try{
onNewItemAddedListener = (OnNewItemAddedListener)activity;
}catch (ClassCastException e)
{
throw new ClassCastException(activity.toString()+" must implement OnNewItemAddedListener");
}
}
}
[MyTextView.java]
package com.jiao.android.todolist;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.TextView;
public class MyTextView extends TextView{
public MyTextView(Context context,AttributeSet attrs, int defStyle)
{
super(context,attrs, defStyle);
// do not forgot to call the ini() method, otherwise, allt he paint objects
// won't be initialized
init();
}
public MyTextView (Context context)
{
super(context);
// do not forgot to call the ini() method, otherwise, allt he paint objects
// won't be initialized
init();
}
public MyTextView(Context context, AttributeSet attrs)
{
super(context, attrs);
// do not forgot to call the ini() method, otherwise, allt he paint objects
// won't be initialized
init();
}
private Paint marginPaint;
private Paint linePaint;
private int paperColor;
private float margin;
private void init(){
//Get a referencve to our resource table
Resources myResources = getResources();
//Create the paint brushes we will use in the onDraw method.
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(myResources.getColor(R.color.notepad_margin));
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(myResources.getColor(R.color.notepad_lines));
System.out.println("line paint is"+linePaint.getColor());
//Get the paper background color and the margin width.
paperColor = myResources.getColor(R.color.notepad_paper);
margin = myResources.getDimension(R.dimen.notepad_margin);
}
#Override
public void onDraw(Canvas canvas){
//Color as paper
canvas.drawColor(paperColor);
//Draw ruled lines
//drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
canvas.drawLine(0, 0,0, getMeasuredHeight(), linePaint);
canvas.drawLine(0, getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight(), linePaint);
//Draw Margin
canvas.drawLine(margin,0,margin,getMeasuredHeight(), marginPaint);
//Move the text across from the margin
canvas.save();
//The translate() method remaps the (0,0) position on the canvas
//or you can think you move the canvas
//Translate - Basically do what it says. Just translate the canvas using x,y.
//If you want to draw two objects and the one is just translation of the other e.g x2 = x1 + 50 for each point .
//You don't have to make all your calculations again for the second object but you can just translate the canvas
//and draw again the same object.
canvas.translate(margin,0);
super.onDraw(canvas);
//This call balances a previous call to save(),
//and is used to remove all modifications to the matrix/clip state since the last save call.
//canvas.save and canvas.restore undo things like rotation and translation. They don't undo drawing on the canvas.
canvas.restore();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent){
return super.onKeyDown(keyCode, keyEvent);
}
}
[ToDoListFragment.java]
package com.jiao.android.todolist;
import android.app.ListFragment;
public class ToDoListFragment extends ListFragment {
}
[ToDoListPlainFragment.java]
package com.jiao.android.todolist;
import android.app.ListFragment;
public class ToDoListPlainFragment extends ListFragment {
}
Below are the layout xml files:
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/swapButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/swap_button_text"
android:onClick="onSwapButtonClicked"
android:layout_weight="2"
/>
</LinearLayout>
<FrameLayout
android:id="#+id/item_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
[new_item_fragment.xml]
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/addItemHint"
android:contentDescription="#string/addItemContentDescription" />
[todolist_item.xml]
<?xml version="1.0" encoding="utf-8"?>
<com.jiao.android.todolist.MyTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:scrollbars="vertical"
android:textColor="#color/notepad_text"
android:fadingEdge="vertical"
/>
Here is the [AndroidManifest.xml]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jiao.android.todolist"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="11" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.jiao.android.todolist.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Try this..
You have given your LinearLayout height as match_parent so it will match the whole parent that's why FrameLayout is not showing. Give LinearLayout height as wrap_content and try it.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" // change is here
android:orientation="horizontal" >
<Button
android:id="#+id/swapButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:onClick="onSwapButtonClicked"
android:text="swap_button_text" />
</LinearLayout>
<FrameLayout
android:id="#+id/item_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<FrameLayout
android:id="#+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

Related

Android inflating views from other layouts

I'm relatively new to android development and I'm trying to find a way to inflate a view repeatedly each time when a button is pressed, in a different location, so every inflated view has its own position:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class teamCreateScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.team_locate_layout);
}
public void createTeam(View view) {
final RelativeLayout rlTeam = (RelativeLayout) findViewById(R.id.rlTeam);
View teamBox = View.inflate(this, R.layout.team_box, rlTeam);
final TextView teamBoxView = (TextView) findViewById(R.id.team_task_box);
teamBoxView.setX(0);
teamBoxView.setY(230);
}
}
The XML code of the layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rlTeam">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="#+id/teamAddBtn"
android:text="+"
android:textSize="30sp"
android:onClick="createTeam"/>
</RelativeLayout>
XML code of the view that's being inflated:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="192dp"
android:layout_height="120dp"
android:id="#+id/team_task_box"
android:text="New Team" />
</RelativeLayout>
I want to use the same view to inflate multiple boxes with different coordinates in the layout. Every time I press the button to inflate the view again it inflates the box in the same coordinates so they overlap. I need to make the second box to appear to the first one's right, the third below 1st and so on, much like a grid of boxes.
Try this code and tell me whether it works. Remove the inflating of layout
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class teamCreateScreen extends Activity {
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.team_locate_layout);
}
public void createTeam(View view) {
final RelativeLayout rlTeam = (RelativeLayout) findViewById(R.id.rlTeam);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
TextView tv=new TextView(getApplicationContext());
if(tv.getId()>0) {
relativeParams.addRule(RelativeLayout.BELOW, tv.getId());
}
tv.setId(i);
r1Team.addView(tv, relativeParams);
i++;
}
}
Declare int i=0; as a global variable and increment it in the createTeam() method.

Strange behavior with Android view.invalidate()

I have 3 custom views placed vertically in a LinearLayout, they are used to display different dynamic info, so they're supposed be invalidated and redrawn at different time. But I found the view invalidation is out of usual expectation, that is: if you invalidate the top view,all 3 views are invalidated at the same time, if you invalidate the middle view, the middle and bottom views are invalidated, the top one is not, if you invalidate the bottom view, only the bottom view itself is invalidated, this is what I want, so what happened with the first 2 cases ? I searched and got similar questions like:
https://stackoverflow.com/questions/26192491/invalidate-one-view-force-other-views-invalidate-too-how-separating-that
Android Invalidate() only single view
but it seems no exact answer. I post my code here, any comment is appreciated.
TestView.java
package com.vrb.myview;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class TestView extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onTest(View view){
MyView1 mv1 = (MyView1)findViewById(R.id.mv1);
MyView1 mv2 = (MyView1)findViewById(R.id.mv2);
MyView1 mv3 = (MyView1)findViewById(R.id.mv3);
mv1.invalidate(); // all 3 views are invalidated
// mv2.invalidate(); // mv2 and mv3 are invalidated
// mv3.invalidate(); // only mv3 is invalidated,this is what I want
}
}
MyView1.java
package com.vrb.myview;
import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class MyView1 extends View {
Rect rc=null;
Paint p=null;
Random r;
public MyView1(Context ctx){
super(ctx);
rc = new Rect();
p = new Paint();
r = new Random();
}
public MyView1(Context ctx, AttributeSet set){
super(ctx, set);
rc = new Rect();
p = new Paint();
r = new Random();
}
public void onDraw(Canvas canvas){
if(canvas.getClipBounds(rc)){
Log.d("MyView1","id="+getId()+" Rect: "+rc.left+","+rc.top+","+rc.right+","+rc.bottom);
p.setColor(Color.argb(0xff, Math.abs(r.nextInt())%255, Math.abs(r.nextInt())%255, Math.abs(r.nextInt())%255));
canvas.drawRect(rc, p);
}else{
Log.d("MyView1","id="+getId()+" Rect=null");
}
}
}
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/root"
android:orientation="vertical"
tools:context="com.vrb.myview.TestView" >
<com.vrb.myview.MyView1
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/mv1" />
<com.vrb.myview.MyView1
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/mv2" />
<com.vrb.myview.MyView1
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/mv3" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Invalidate"
android:onClick="onTest"
android:id="#+id/btn" />
</LinearLayout>
You shouldn't rely on the count or the time of the calls to onDraw() for the internal state of your View. Move the p.setColor() call to a separate public method, and call invalidate() at the end of it. For example:
public class MyView1 extends View {
...
public void changePaint() {
p.setColor(Color.argb(0xff, Math.abs(r.nextInt()) % 255, Math.abs(r.nextInt()) % 255, Math.abs(r.nextInt()) % 255));
invalidate();
}
}
Then in your onTest() method:
public void onTest(View view) {
MyView1 mv1 = (MyView1)findViewById(R.id.mv1);
...
mv1.changePaint();
...
}

How to Change a size of fragment?

Pretty new to android development, I need to know how I can change the size of my ListView in my fragment pragmatically to cover the entire screen? match_parent, fill_parent didn't work.
I have hard coded values of 500dp
Here is my fragment
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#android:id/list"
android:layout_width="500dp"
android:layout_height="500dp"
android:divider="#null"
android:dividerHeight="0dp"
android:layout_marginTop="0dp">
</ListView>
</RelativeLayout>
and here is JAVA my fragment code:
import android.app.ListFragment;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import java.util.List;
public class MyFragment extends ListFragment {
List<data> flowers = new datadata().getdatas();
public MyFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dataArrayAdapter adapter = new dataArrayAdapter(getActivity(),
R.layout.data_listitem,
flowers);
setListAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.my_fragment, container, false);
return rootView;
}
}
here is my main Activity class
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbarStyle="insideOverlay"
android:scrollbars="none"
android:fadeScrollbars="true"
android:fitsSystemWindows="true"
android:layout_gravity="top"
>
</ScrollView >
and this is my main activity java code:
package mshirvan.example.com.netplex;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Intent;
import android.media.Image;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.view.View.OnClickListener;
import data.row1;
public class MainActivity extends Activity {
public static float screenx = 0;
public static float screeny = 0;
public static int screenpixelx = 0;
public static int screenpixely = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ScreenUtility utility = new ScreenUtility(this);
screenx = utility.getWidth();
screeny = utility.getHeight();
screenpixelx = utility.getPixelWidth();
screenpixely = utility.getPixelHeight();
MyFragment frag = new MyFragment();
getFragmentManager().beginTransaction()
.add(R.id.myContainer, frag)
.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
ScreenUtility utility = new ScreenUtility(this);
String output = "Width: " + utility.getWidth() + ", " +
"Height: " + utility.getHeight();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Add the following to your fragment RelativeLayout. This should be as follows:
android:layout_width="match_parent"
android:layout_height="500dp"
For example the map layout fragment should be as follows :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="500dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity"
>
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
Then add this fragment layout in the main layout.
put these in your listview too:
android:layout_width="match_parent"
android:layout_height="match_parent"
or you can change the layoutparameters to match_parent in yout fragment
that contains the listview.
you have to set the fragment container height to match parent not ListView. in your case ,ListView will fill it's parent height. ListView's parent is RelativeLayout and the RelativeLayout height is matchParent that means , RelativeLayout will also fill it's container and it's container is your fragment place holder that defined in your activity's layout file. you have to set that container's height to matchParent.
I think the problem is that you are trying to add fragment to ScrollView. use FrameLayout with android:layout_height=match_parent for fragment's container and if you have to add multiple fragments, then define multiple FrameLayouts in your activity's layout or add them dynamically.

Second of two fragments only displayed in landscape mode: Layout bug or lifecycle issue?

I want to be able to dynamically change the content of two fragments, the one on the left (in landscape mode) resp. on top (in portrait mode) playing videos (a VideoView) and the one on the right (landscape) resp. at the bottom (portrait) showing text (a TextView). So I created a MainActivity.java which only displays the layout container (activity_main.xml), a VideoFragment.java and its layout file (fragment_video.xml), and a TextFragment.java and its layout file (fragment_text.xml). Since I want the videos (which are cut into a square shape) to be displayed in a square (same size in landscape and portrait), I overwrote LinearLayout's onMeasure method in SquareLayout.java.
Now the (not so) funny (anymore) thing is that everything works fine in landscape orientation, yet in portrait mode the TextView is not displayed. (I have to add that the orientation change is "implemented" through the "lazy" onConfigurationChanged method of the two fragments.) I tend to think that there is a bug in the nested LinearLayouts and their width and height parameters, but I could not yet figure out (by changing these parameters) where exactly the bug would be located. I also tried to visualize the usage of lifecycle methods (with Toasts) and things seemed as one would expect, i.e. while onConfigurationChanged was in place, it was used during orientation change and onPause and onResume were not, and while onConfigurationChanged was not in place, onPause and onResume were used. That is to say that the TextView existed. Any ideas anyone? Thanks!
Here is my code:
MainActivity.java
package org.myPackage.myApp;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
VideoFragment.java
package org.myPackage.myApp;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.MediaController;
import android.widget.VideoView;
public class VideoFragment extends Fragment {
VideoView videoView;
int position;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_video, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
videoView = (VideoView) getView().findViewById(R.id.video);
Uri uri = Uri.parse("android.resource://"
+ getActivity().getPackageName() + "/" + R.raw.clip);
videoView.setVideoURI(uri);
MediaController mediaController = new MediaController(getActivity());
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.start();
}
#Override
public void onPause() {
position = videoView.getCurrentPosition();
super.onPause();
}
#Override
public void onResume() {
videoView.seekTo(position);
super.onResume();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
TextFragment.java
package org.myPackage.myApp;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class TextFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return(inflater.inflate(R.layout.fragment_text, container,
false));
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
TextView textView = (TextView) getView().findViewById(R.id.text);
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.BLACK);
textView.setMovementMethod(new ScrollingMovementMethod());
textView.setPadding(12, 6, 6, 12);
textView.setText("Lorem ipsum dolor sit amet, ...");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
SquareLayout.java
package org.myPackage.myApp;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
public class SquareLayout extends LinearLayout {
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int size = widthSize < heightSize ? widthSize : heightSize;
int finalMeasureSpec = MeasureSpec.makeMeasureSpec(size,
MeasureSpec.EXACTLY);
super.onMeasure(finalMeasureSpec, finalMeasureSpec);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<fragment
android:id="#+id/fragment_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
class="org.myPackage.myApp.VideoFragment" />
<fragment
android:id="#+id/fragment_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
class="org.myPackage.myApp.TextFragment" />
</LinearLayout>
fragment_video.xml
<?xml version="1.0" encoding="utf-8"?>
<org.MyPackage.MyApp.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<VideoView
android:id="#+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</org.MyPackage.MyApp.SquareLayout>
fragment_text.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.MyPackage.MyApp"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="org.MyPackage.MyApp.MainActivity"
android:configChanges="orientation|screenSize"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Shape Drawable View in XML

I'm using the shapedrawable example word for word (nearly) and can't seem to call a shapedrawable class in xml. The only extra step stated by the documentation was to override the View(Context, AttributeSet), which I think I did. The docs I'm referring to are here: http://developer.android.com/guide/topics/graphics/2d-graphics.html Here is my code.
AndroidTest.java
package com.android.test;
import android.app.Activity;
import android.os.Bundle;
public class AndroidTest extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
ShapeSquare.java
package com.android.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;
public class ShapeSquare extends View {
private ShapeDrawable mDrawable;
public ShapeSquare(Context context, AttributeSet attrs) {
super(context, attrs);
int x = 10;
int y = 10;
int width = 300;
int height = 50;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.android.test.shapedrawable.ShapeSquare
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
The error is a force quit error and I can't figure out where the problem lies. The shape properties will be dictated by user input (eventually), so the shape needs to be created in a class as opposed to all xml.
Figured out the problem here. I had to remove "shapedrawable" from:
<com.android.test.shapedrawable.ShapeSquare
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
Apparently, that was just the location of the demo. I thought it was referencing the class somehow.

Categories

Resources