This is a common problem and with a variety of solutions. In the solution I'll show you in a little while we check in our Activity if there is an id for the 2nd Fragment ( the one that will play the role of the DetailFragment ).
One common tactic is having two different versions of the xml layout we are wokring on. One in the layout folder and another one in the layout-sw600dp or whatever we define for the dual mode.
The 2nd file contains one more FrameLayout so what we basically have to do is check if the view is there. If its true then we are on a dual mode, if not then we are on a single mode.
First we define a Boolean isDualMode with false as an initial value.
Then on onCreate we check for the details id :
View aView = findViewById(R.id.details);
if (aView != null) {
isDualPane = true;
}
If thats true we add and commit the DetailsFragment also.
Full code for onCreate() :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View aView = findViewById(R.id.details);
if (aView != null) {
isDualPane = true;
}
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
mainFragment = new MainFragment();
if (isDualPane) {
detailsFragment = new DetailsFragment();
fragmentManager.beginTransaction().add(R.id.details, detailsFragment).commit();
}
fragmentManager.beginTransaction().add(R.id.main, mainFragment).commit();
fragmentTransaction.commit();
}
Android Java TI
Thursday, May 28, 2015
Thursday, May 21, 2015
Set text size for Toolbar
Since Toolbar doesnt provide a textSize attribute to set the text size of the Title you have to add a TextView and pass the title text to it.
Ofcourse you can instead use setTitleTextAppearance where you can set color, size, style etc.
For the first solution the steps you got to follow are :
1) remove default title :
2) Add TextView in Toolbar :
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:minHeight="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:background="@color/colorPrimary"
android:theme="@style/ActionBarThemeOverlay"
android:popupTheme="@style/ActionBarPopupThemeOverlay">
<TextView
android:id="@+id/tv_toolbar"
android:textSize="@dimen/toolbar_textSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
3) Set toolbar_textSize on dimens.xml :
<dimen name="toolbar_textSize">16sp</dimen>
Now toolbar's title size is the one you specify on the dimens.xml file. That's it 16sp in our code.
We prefer sp units (instead of dp) so the size can scale when user changes the font size on her/his device.
Ofcourse you can instead use setTitleTextAppearance where you can set color, size, style etc.
For the first solution the steps you got to follow are :
1) remove default title :
getSupportActionBar().setDisplayShowTitleEnabled(false);
2) Add TextView in Toolbar :
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:minHeight="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:background="@color/colorPrimary"
android:theme="@style/ActionBarThemeOverlay"
android:popupTheme="@style/ActionBarPopupThemeOverlay">
<TextView
android:id="@+id/tv_toolbar"
android:textSize="@dimen/toolbar_textSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
3) Set toolbar_textSize on dimens.xml :
<dimen name="toolbar_textSize">16sp</dimen>
Now toolbar's title size is the one you specify on the dimens.xml file. That's it 16sp in our code.
We prefer sp units (instead of dp) so the size can scale when user changes the font size on her/his device.
Thursday, May 15, 2014
ActionBar dissapears although I'm using a scrollView
ActionBar dissapears when I click EditText although I'm using a ScrollView. This behavior appears after an orienation change when I click the EditText view.
Solution :
Seems that I need to add also adjustResize on my manifest :
android:windowSoftInputMode="adjustResize"
Solution :
Seems that I need to add also adjustResize on my manifest :
android:windowSoftInputMode="adjustResize"
//TODO
further investigate that behavior
Sunday, February 23, 2014
ToDo List example
Since repetition is the mother of all
learning and the following example is one of the most distinct
examples of how to start android
development I wrote it down as well
to try to explain it as best as I can.
What we are going to do is a ToDo
List app.
Bearing the design in mind will help us
better understand what components will be needed ( plus I prefer a
more visualized approach
to such kind of problems ).
As we can see from the mockup sketch
two fragments are needed. One will just display an EditText widget
and when the user clicks
'Send' on the software keyboard we will
pass the text to the list bellow. That gets us to the second fragment
which is a ListFragment.
Both of them are in the MainActivity.
Since we are using a ListFragment we
have to use an Adapter to bind the data to the list.
Also we will need a data model for our
todo items. Lets name it DataItem class.
Last but not least we will create a
custom view from each list item.
Let me summarize things a little bit : We have one MainActivity class with its layout, composed of two
fragments ( one is a ListFragment ). The ListFragment also needs an
Adapter class. Our data model will only need a String variable and a
Custom View for each ListFragment's item for the time.
So let's start from our model. We only
need one getter and one setter method since our only variable will be
a String. You can check the code here .
Now its time to create the TopFragment.
As you can see
the layout is just an EditText. We inflate that layout in onCreateView method ( like we do with every fragment ). The “tricky” part here is adding an OnEditorActionListener so we can listen for the 'SEND' action, get the user input and clear the text in EditText. An Interface is also necessary so we can implement it on the MainActivity and get the user's text input. All of these data will be stored on an ArrayList in the MainActivity and passed to the Adapter to bind them to the view.
The
TaskListAdapter gets each item from the ArrayList as we said above,
creates a new list item and sets the data.
ListFragment
just inflates the layout which consists of a ListView with the
android:divider
atrribute
set to null so we don't have to deal with the default divider line
from the ListView widget.
Since
each item is just a TextView our custom view needs to extend a
TextView. We saw on a previous post how to
create a custom view so I will not go into details.
The
XML layout file for the custom view, used by the TaskListAdapter is:
That input along with the id resource of the XML file that represents the list
item are passed to the Adapter.
The code is below :
public class MainActivity extends Activity implements TopFragment.OnItemAddedListener { private ArrayListtodoItems; private TaskListAdapter aa; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get references to the Fragments FragmentManager fm = getFragmentManager(); TaskListFragment todoListFragment = (TaskListFragment)fm.findFragmentById(R.id.TaskListFragment); // Create the array list of to do items todoItems = new ArrayList (); // Create the array adapter to bind the array to the ListView int resID = R.layout.tasklist_fragment; aa = new TaskListAdapter(this, resID, todoItems); // Bind the array adapter to the ListView. todoListFragment.setListAdapter(aa); } public void onNewItemAdded(String newItem) { DataItem newTodoItem = new DataItem(newItem); todoItems.add(0, newTodoItem); aa.notifyDataSetChanged(); } }
The method onNewItemAdded() adds the DataItem before every other ArrayList item and also notify the data set has changed.
You can find the code of the project in the github repo here and you can import it and run it on your eclipse.
This example is based on Reto Meier's example on chapter four of his book "Professional Android 4 Application Development" you can find in this link
Sunday, December 29, 2013
Custom Views
We
get Custom Views by extending an existing Widget ( Button, EditText,
TextView, etc ), something that fits better to the functionality we
want to achieve and by defining attributes for that view.
1.
By extending a View we now have a Class, whose fully qualified name
can be used as an XML tag, to add to the layout file. If the package
is com.androidexamples.customviews and my Custom View's Class name is
MyEditText then the XML code we are going to add is :
<com.androidexamples.customviews.MyEditText
android:id=”@+id/myview”
android:layout_width="match_parent"
android:layout_height="wrap_content"
…
/>
2.
Into res/values/attrs.xml inside a <declare-styleable> tag we
add the attributes for our view. A valid example could be :
<resources>
<declare-styleable>
<attr
name=”attr_color” format=”color” />
<attr
name=”attr_firstname” format=”string” />
</declare-styleable>
</resources>
From now on we can use these attributes
either in our layout file as part of our custom View XML tag, or
through code.
In order to use them in the layout file
we have to first define a custom namespace similar to what android
does with its own attributes. The android default namespace is :
xmlns:android="http://schemas.android.com/apk/res/android”
and it's defined into the
parent element of the layout file.
Respectively our attributes' namespace uses the same format but instead of android we can use whatever name we want ( like “app” or “custom” ) and the schema is defined with our package name instead of the android. So a valid example could be :
Respectively our attributes' namespace uses the same format but instead of android we can use whatever name we want ( like “app” or “custom” ) and the schema is defined with our package name instead of the android. So a valid example could be :
xmlns:app="http://schemas.android.com/apk/res/com.androidexamples.customviews"
Now
we can add the “attr_firstname” to the XML in the form :
app:attr_firstname=”Some
Random Text”
Through
the code we have access to an array that stores each attribute. It is
a special container named TypedArray
and it can get referenced to the attributes with
obtainStyledAttributes().
3. In our Class code it is a
common practise to use an init() method to get the attributes and
assign initial values to them. This method is then passed to our
View's constructor.
4. Then all it's left to do is
to override the onDraw() and onMeasure() methods.
By
overriding onDraw()
we have access to the Canvas object. You can now create your UI for
your View. The styling of the elements is done through a Paint
object.
OnMeasure()
is called with the width and height specifications from the parent
layout element. Those values should be treated as requirements for
the restrictions on width and height measurements we will produce.
Some key points you should keep in mind
( otherwise it leads you to hard ) :
- call recycle() after you get the attributes from TypedArray.
- Don't create Paint objects inside onDraw() method. Views are redrawn frequently and creating objects inside onDraw() its expensive waste of resources.
- After every change on our attributes' values we have to call invalidate() so the system will know there might be a change in its appearance and needs to be redrawn.
The code below gives as a custom EditText which uses Paint to underline each line with a light green color.
public class MyEditText extends EditText { private Rect mRect; private Paint mPaint; private int attrColor; public MyEditText(Context context) { super(context); } public MyEditText(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyEditText); attrColor = ta.getInteger(R.styleable.MyEditText_attr_color, 0xff00ff00); ta.recycle(); init(); } public void init() { mRect = new Rect(); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(attrColor); //get value from attr } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int count = getLineCount(); Rect r = mRect; Paint p = mPaint; for(int i=0; i< count; i++) { int baseline = getLineBounds(i, r); canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, p); } } }
Monday, December 9, 2013
Add Views programmatically
Example of adding two Buttons in a RelativeLayout :
1) Instantiate the RelativeLayout
2) Instantiate the Buttons.
3) Create the LayoutParams for each Buttons.
4) Add Views to their parent. That's the RelativeLayout.
One key point here. The LayoutParams for the child Views must the same type as that of their parent. So in our case both Buttons LayoutParams have to be RelativeLayout.LayoutParams.
Let's see how this applies to code :
RelativeLayout layout = new RelativeLayout(this); // Instantiate the parent
b3 = new Button(this); b3.setId(1);
b3.setText("Relative Button 3");
b4 = new Button(this); b4.setId(2);
b4.setText("Relative Button 4");
RelativeLayout.LayoutParams b3_lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams b4_lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
b4_lp.addRule(RelativeLayout.RIGHT_OF, b3.getId());
layout.addView(b3, b3_lp);
layout.addView(b4, b4_lp);
setContentView(layout);
The result is :
Notice the addRule() which sets the Button b4 to the right of the b3.
To achieve that we have to set Id's for our Buttons so we can refer to the view that acts as an anchor.
1) Instantiate the RelativeLayout
2) Instantiate the Buttons.
3) Create the LayoutParams for each Buttons.
4) Add Views to their parent. That's the RelativeLayout.
One key point here. The LayoutParams for the child Views must the same type as that of their parent. So in our case both Buttons LayoutParams have to be RelativeLayout.LayoutParams.
Let's see how this applies to code :
RelativeLayout layout = new RelativeLayout(this); // Instantiate the parent
b3 = new Button(this); b3.setId(1);
b3.setText("Relative Button 3");
b4 = new Button(this); b4.setId(2);
b4.setText("Relative Button 4");
RelativeLayout.LayoutParams b3_lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams b4_lp = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
b4_lp.addRule(RelativeLayout.RIGHT_OF, b3.getId());
layout.addView(b3, b3_lp);
layout.addView(b4, b4_lp);
setContentView(layout);
The result is :
Notice the addRule() which sets the Button b4 to the right of the b3.
To achieve that we have to set Id's for our Buttons so we can refer to the view that acts as an anchor.
Sunday, November 24, 2013
Send JSON unicode data to server with POST request
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url); // Address ( url )
HttpResponse response;
JSONObject json = new JSONObject();
json.put("passwd", param1);
json.put("comment", param2);
// String Entity to UTF-8
StringEntity se = new StringEntity(json.toString(), "UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.getParams().setParameter("json", json);
httppost.setEntity(se);
response = httpclient.execute(httppost);
HttpPost httppost = new HttpPost(url); // Address ( url )
HttpResponse response;
JSONObject json = new JSONObject();
json.put("passwd", param1);
json.put("comment", param2);
// String Entity to UTF-8
StringEntity se = new StringEntity(json.toString(), "UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.getParams().setParameter("json", json);
httppost.setEntity(se);
response = httpclient.execute(httppost);
Subscribe to:
Posts (Atom)