when user presses a button i would like to switch to the 'details' layout which is like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layoutDetails"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16dp"
android:textColor="#ff0000"
android:text="Category" />
<TextView android:id="#+id/tv_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dp"
android:layout_marginLeft="10dp" />
</LinearLayout>
and this is how i am trying to switch it:
switch(item.getItemId())
{
case ID_DETAILS:
// show new layout to for details
LinearLayout detailsLayout = (LinearLayout) findViewById(R.id.layoutDetails);
LayoutInflater detailsvi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View detailsv = detailsvi.inflate(R.layout.activity_details, null);
// IT CRASHES ON THIS LINE
detailsLayout.addView(detailsv,new LinearLayout.LayoutParams(detailsLayout.getLayoutParams().width, detailsLayout.getLayoutParams().height));
return true;
}
It gives a null pointer exception error!!!
08-09 17:23:47.146: E/AndroidRuntime(1572): FATAL EXCEPTION: main
08-09 17:23:47.146: E/AndroidRuntime(1572): java.lang.NullPointerException
Here is how you solve this:
1) put a breakpoint on the crashline and run in debug mode. You can immediately see if detailsLayout is null or not. If not do step 2 Also check if detailsv is null.
2) details
Object o1 = etailsLayout.getLayoutParams(); // check if this is null.
It has to be one or the other.
Update: Since its detailsLayout is in fact null. It must be that either
1) setContentView was not called prior to requsting detailsLayout, or
2) setContentView was set to a layout that did not define detailsLayout, or
3) setContentView was called correctly but detailsLayout is not correctly id in that layout file.
It must be one of these three.
Related
Have spent time reading the posts and did not find anything relevant to the issue experiencing.
Have an android Marshmallow based application that launches an activity which has a layout containing a listview. Have written a custom adapter which does have it's getView method called and have confirmed that the data is present. The getView from the adapter is:
ArrayList<HashMap<String,IncidentData>> localList;
mLayoutInflator = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mLayoutInflator.inflate(R.layout.list_item_base_incident, parent,false);
}
mDateTimeText = (TextView)convertView.findViewById(R.id.date_time_text);
mAddressText = (TextView)convertView.findViewById(R.id.address_text);
mDistanceToText = (TextView)convertView.findViewById(R.id.distance_to_text);
mShortDescText = (TextView)convertView.findViewById(R.id.short_desc_text);
mGangRelatedText = (TextView)convertView.findViewById(R.id.gang_related_text);
//pop data
HashMap<String,IncidentData>incident2 = mID.get(position);
IncidentData id = incident2.get(incident2.keySet().iterator().next());
mDateTimeText.setText(id.getDateTime());
mAddressText.setText(id.getAddress());
mDistanceToText.setText(String.valueOf(id.getDistance()));
mShortDescText.setText(id.getShortDesc());
mGangRelatedText.setText(id.getGangRelated());
Log.d(LOG_TAG,"SHORT DESC - "+ id.getShortDesc());
return convertView;
}
Log message shows the getView processing each entry in the hashmap correctly. The issue is that the data is not appearing in the listview however, the listview does display the correct number of blank entries for the amount of data.
Screen layout is as follows:
incident_layout_base.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">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/incident_list_view"/>
</LinearLayout>
and the layout for the listview contents is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:columnCount="1">
<TextView
android:id="#+id/date_time_text"
app:layout_columnWeight="1"
tools:text="08201624#2350"/>
<TextView
android:id="#+id/address_text"
app:layout_columnWeight="1"
tools:text="SAN FERNANDO BLVD AND ALAMEDA AVE"/>
<TextView
android:id="#+id/distance_to_text"
app:layout_columnWeight="1"
tools:text="1"/>
<TextView
android:id="#+id/short_desc_text"
app:layout_columnWeight="1"
tools:text="Murder"/>
<TextView
android:id="#+id/gang_related_text"
app:layout_columnWeight="1"
tools:text="gang related"/>
</android.support.v7.widget.GridLayout>
The application does launch an intent to handle the display containing the listView. The intent calls setContentView, gets the data, instantiates the custom adapter and calls setAdapter on it.
Ideas appreciated
Found the issue for no data being displayed. The background and the text color default to white. So, while the data was there, yoiu couldn't see it.
I have a code to change text as on create
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
Button btnbut = FindViewById<Button>(Resource.Id.btnbut);
TextView txtvw = FindViewById<TextView>(Resource.Id.txtView);
txtvw.Text = "Hello World";
btnbut.Text = "Hello WOrld";
}
}
My main.axml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linearLayout1">
<TextView
android:layout_width="match_parent"
android:layout_height="47.5dp"
android:id="#+id/txtView"
android:layout_marginLeft="1.0dp"
android:layout_marginRight="0.0dp" />
<Button
android:text="Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnbut" />
</LinearLayout>
When I run and open app with emulator the Text has remain the same as define on main.axml not the text define OnCreate.
Your code is correct and should result in:
Try performing a clean all/build all on your solution and retry your app on the emulator again.
Note: If it is still not updating the app on the emulator correctly:
Within the emulator:
Setting / Apps / Select your app / *Uninstall*
i think i got your i dont use xamrain but i think this is the error try changing
SetContentView(Resource.Layout.Main);
to
SetContentView(Resource.Layout.My main);
coz your layout name is "My main" not "main"
Does anybody know how to programmatically set the text of a button?
thing is i'm not calling this from the main layout(setContentView) i'm calling it in a view thats inflated after an asynctask
heres what i have tried but this is giving a null pointer exception on the 2nd line
Button mButton=(Button)findViewById(R.id.contact);
mButton.setText("number");
heres my layout where i am calling the button
<Button
android:id="#+id/contact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/address"
android:layout_toLeftOf="#+id/badge"
android:background="#drawable/ic_btn_call"
android:textSize="10dp"
android:textStyle="bold"
android:textColor="#color/white"/>
here my view i'm inflating
ClubInfo = LayoutInflater.from(getBaseContext()).inflate(R.layout.clubinfocell,
null);
TextView TeamNameText = (TextView) ClubInfo.findViewById(R.id.TeamName);
TeamNameText.setText(teamName);
TextView AddressText = (TextView) ClubInfo.findViewById(R.id.address);
AddressText.setText(address1);
Button mButton=(Button)ClubInfo.findViewById(R.id.contact);
mButton.setText(telephone);
Then use your view's object to initialize it:
Button mButton = (Button)your_view_object.findViewById(R.id.contact);
mButton.setText("number");
When you try to identify a view other than your Activity's layout, you have to pass the reference of that view like this. If not Android will keep looking for this element from the layout which you provided in the setContentView().
For example, consider you have inflated a view like this:
View View = mInflater.inflate(R.layout.gridelement, null);
Then use this View's object for the Button present in that inflated layout:
Button mButton = (Button)View.findViewById(R.id.contact);
change your code as:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);//set layout here in which u have add contact in xml
Button mButton=(Button)findViewById(R.id.contact);
mButton.setText("number");
EDIT:
Your \res\layout\main.xml look like as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/contact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/address"
android:layout_toLeftOf="#+id/badge"
android:background="#drawable/ic_btn_call"
android:textSize="10dp"
android:textStyle="bold"
android:textColor="#color/white"/>
</LinearLayout>
your mButton is null.so NPE.are you refrenced xml resources after setContentView
onCreate(){
...
setContentView(R.layout.yourlayout);
Button mButton=(Button)findViewById(R.id.contact);
mButton.setText("number");
}
check R.java files import statement
are you sure that you have import it of the project you use ..
and just format your layout (.xml ) file save it and again type the same statement
Found a Solution!
I now use a ViewPager instead of a ViewFlipper.
The Views are now generated within my run() method (which is already there because I fetch data from the web) and saveed in a Map.
In my Handler I only call pagerAdapter.notifyDataSetChanged() the pagerAdapter uses the Map of views and it works smooth and fast.
So I'm now looking for a away to have the ViewPager scroll endless, but thats another problem not connected to this one ;)
Thank all of you for your answers and keep up the good support.
I'm quite new to Android development and facing a problem while inflating a (huge) layout.
I getting some Data from a Webservice which works fine then i'm using a handler within my Activity to bring this data to the frontend. Here is my handleMessage:
public void handleMessage(Message msg) {
LayoutInflater inflater = getLayoutInflater();
List<Integer> gamedays = new ArrayList<Integer>(games.keySet());
Collections.sort(gamedays);
for (Integer gameday : gamedays) {
View gamedaytable = inflater.inflate(R.layout.gamedaytable, null);
TableLayout table = (TableLayout) gamedaytable.findViewById(R.id.gameDayTable);
table.removeAllViews();
List<Game> gamelist = games.get(gameday);
int rowcount = 2;
for (Game game : gamelist) {
View tableRow = inflater.inflate(R.layout.gamedayrow, null);
TextView homeTeam = (TextView) tableRow.findViewById(R.id.gameDayHome);
TextView awayTeam = (TextView) tableRow.findViewById(R.id.gameDayAway);
TextView gameResult = (TextView) tableRow.findViewById(R.id.gameDayResult);
gameResult.setBackgroundResource(R.drawable.resultbackground);
homeTeam.setText(game.getHomeTeam().getName());
awayTeam.setText(game.getAwayTeam().getName());
if (game.getHomegoals() < 0 || game.getAwaygoals() < 0) {
gameResult.setText("-:-");
} else {
gameResult.setText(game.getHomegoals() + ":" + game.getAwaygoals());
}
if (rowcount % 2 == 0) {
tableRow.setBackgroundColor(0xffdee0dd);
} else {
// setting alternative background
tableRow.setBackgroundColor(0xfff1f3f0);
}
rowcount++;
table.addView(tableRow);
}
flipper.addView(gamedaytable);
}
flipper.setDisplayedChild(thisgameday - 1);
pd.dismiss();
}
My Problem is that this code runs quite slow and d the processdialog freezes for about 1 second before it disappears and the layout is shown.
games consists of 34 entries which contains 9 entries by itself.
So I'm adding 34 Views consisting of a relativeLayout () which holds the table
I think the problem is, that android starts to draw and calculte the layout and this takes too long.
If I'm correct i can not use AsynTask because i can not do UI stuff there and im doing UI stuff only.
I looking for a way to have the process dialog not freezing while doing this.
Or maybe I'm doing some completly wrong
R.layout.gamedaytable:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff1f3f0"
android:focusableInTouchMode="false" >
<TableLayout
android:id="#+id/gameDayTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:focusableInTouchMode="false" >
</TableLayout>
</RelativeLayout>
R.layout.gamedayrow:
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusableInTouchMode="false"
android:paddingBottom="5dp"
android:paddingTop="5dp" >
<TextView
android:id="#+id/gameDayHome"
style="#style/textsizeSmallScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Mannschaft 1" />
<TextView
android:id="#+id/textView2"
style="#style/textsizeSmallScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text=":" />
<TextView
android:id="#+id/gameDayAway"
style="#style/textsizeSmallScreen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Mannschaft 2" />
<TextView
android:id="#+id/gameDayResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:background="#drawable/resultbackground"
android:paddingLeft="10dip"
android:text="0:5"
android:textColor="#FFFFFF"
android:textSize="11dp"
android:textStyle="bold"
android:typeface="monospace" />
</TableRow>
Additional Info:
This is how the Table should look like.
So i'm not sure if this should really be a ListView because for me its tabledata ;)
table
You seem to be building a list, you should probably look at using a ListView, which'll have the advantages of only needing to build the UI for the number of rows currently being shown, and to also do view re-use, so that you don't need to inflate as many rows.
Found a Solution!
I now use a ViewPager instead of a ViewFlipper. The Views are now generated within my run() method (which is already there because I fetch data from the web) and saveed in a Map. In my Handler I only call pagerAdapter.notifyDataSetChanged() the pagerAdapter uses the Map of views and it works smooth and fast. So I'm now looking for a away to have the ViewPager scroll endless, but thats another problem not connected to this one ;)
Thank all of you for your answers and keep up the good support.
It is better to go for Listview. Even we can add more than one design of rows in the listview in an optimized manner which will improves the performance better.
You definitely can do this on an AsyncTask. While you cannot update the UI on the doInBackground method of an AsyncTask, you can from the onProgressUpdate.
I would break up the code so you are iterating through items while in doInBackground, call publishProgress for each item, and then do the UI updates for the item when you get a callback in onProgressUpdate.
I have a bug with my activity.
I have three view stubs in my linear layout like so -
<ViewStub
android:id="#+id/index_1"
android:layout="#layout/index_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ViewStub
android:id="#+id/index_2"
android:layout="#layout/index_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ViewStub
android:id="#+id/index_3"
android:layout="#layout/index_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
my onCreate conditionally checks what to inflate:
for (int i = 0; i < 3; i++) {
int id = convertIndexToId(i); //will turn i into R.id.index_1
ViewStub stub = findViewById(id);
if (bShouldBeSpinner) {
stub.setLayoutResource(R.layout.index_spinner);
View root = stub.inflate();
Spinner spin = (Spinner)root.findViewById(R.id.my_spinner);
spinner.setAdapter(adapter);
spinner.setSelection(0);
}
else {
stub.setLayoutResource(R.layout.index_edittext);
View root = stub.inflate();
EditText et = (EditText)root.findViewById(R.id.my_edittext);
//et.phoneHome(); just kidding
et.setText(String.valueOf(System.currentTimeMillis()));
}
}
I force bShouldBeSpinner to false. The output of the edittext's is as follows:
1300373517172
1300373517192
1300373517221
However, when I rotate the screen and onCreate is called a second time the output is this:
1300373517221
1300373517221
1300373517221
Initially that made me think you should only inflate the view once, and the heirarchy is kept inbetween onCreate's... however when i only run it the first time the second time no views are shown for the stubs.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Spinner style="#style/SearchInput" android:id="#+id/my_spinner" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText style="#style/SearchInput" android:id="#+id/my_edittext" />
</LinearLayout>
I feel the documentation is assuming something that I did not notice or am missing. Does anyone see what I am doing wrong?
EDIT
I added to the view stubs android:inflatedId="index_1_root"... etc
it is the strangest thing, when I add these lines after the for loop:
EditText v = indexRoot1.findViewById(R.id.index_edit_text);
Log.d(TAG, "EditTExt: " + v);
EditText v2 = indexRoot2.findViewById(R.id.index_edit_text);
Log.d(TAG, "EditTExt: " + v2);
the output says (I believe) they are references to different EditTexts.
EditTExt: android.widget.EditText#47210fe8
EditTExt: android.widget.EditText#47212ba8
So they are getting inflated again, but the text is set to what the last edittext was set to on the first pass.
There may be some issues when recreating views of different types with the same id.
ViewStub is replaced by inflated view.
I suggest using
setInflatedId(int inflatedId)
to distinguish inflated views.
Hope that help.
Instead of using ViewStubs, I added an id to the root of those stubs (android:id="index_roots") and used
view.addView( (isSpinner) ?
new Spinner(this) : new EditText(this) );
to fix this problem, I will however not accept this answer right away, I'll allow others to answer using the method I was going for.