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.
Related
I have an expandable list view that houses a short survey (3-4 fields for a user to insert data about) per record that we have. Then we have a button that they can hit to submit the data to our server. When they hit the button I need it to grab all the data in the surveys and send it to our site. I have the sending portion of it figured out; what I'm struggling with is grabbing all the data from the survey.
I've looked through many of the related posts/google results and attempted to implement and adapt their solution for listviews to expandedlistviews but I have not been able to get any of them working. I've spent quite a few hours trying to get some workable solution but alas, I cannot figure it out.
I think part of my problem is I'm not exactly certain how children views come into play for expandable list views. In any event below is my code in hopes that someone smarter than me can help me solve this problem.
So I have my ExpandableListView fragment_survey.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
tools:context="edu.ucr.aum.fragments.SurveyFragment$PlaceholderFragment">
<ExpandableListView
android:id="#+id/list_view_survey_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/rowPaddingMedium"
android:layout_marginRight="#dimen/rowPaddingMedium"
android:divider="#null"
android:dividerHeight="0dp"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay" />
<TextView
android:id="#+id/tvResponseCode"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/list_view_survey_list"
android:text="Response Code: "/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Submit Survey"
android:layout_below="#+id/tvResponseCode"
android:id="#+id/btnSubmitSurvey" />
</RelativeLayout>
And here is my row xml list_view_survey_row.xml:
<TextView
android:id="#+id/tvSurveyTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/surveyTitle" />
<TextView
android:id="#+id/tvSurveyShared"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="#string/surveyShared"
android:layout_below="#+id/tvSurveyTitle"
/>
<RadioGroup
android:id="#+id/radioShared"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvSurveyShared">
<RadioButton
android:id="#+id/radioButtonYes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/yes"
android:focusable="true"/>
<RadioButton
android:id="#+id/radioButtonNo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/no"
android:focusable="true"/>
</RadioGroup>
<TextView
android:id="#+id/tvSurveyReason"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/surveyReason"
android:layout_below="#+id/radioShared" />
<TextView
android:id="#+id/tvSurveyRating"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="#string/surveyRating"
android:layout_below="#+id/tvSurveyReason" />
<CheckBox
android:id="#+id/checkBoxInterest"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/surveyInterestPositive"
android:layout_below="#+id/tvSurveyRating"
android:focusable="true" />
<CheckBox
android:id="#+id/checkBoxPrivacy"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/surveyShareLevelPositive"
android:layout_below="#+id/checkBoxInterest"
android:focusable="true" />
<RatingBar
android:id="#+id/ratingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/checkBoxPrivacy"
android:focusable="true" />
<View android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="#FF00FF00"
android:layout_below="#+id/ratingBar" />
Then I have a fragment (fragment_survey.java) which adds an onclicklistener to the button (btnSubmitSurvey) in the fragment_survey.xml file. That onClickListener() function calls two methods (one to get the data and one to send that data).
this.buttonSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getData(v);submitSurvey();
}
});
public void getData(View view) {
//get data here
}
public void submitSurvey() {
// Create a new HttpClient and Post Header
String url;
if(Singletons.Debug.debug) {
url = "url for postback";
} else {
url = "url for postback";
}
NetworkAsyncTask nat = new NetworkAsyncTask();
try {
String response = nat.execute(url).get();
//Log.d(TAG, "Response: " + response);
} catch(ExecutionException e) {
} catch(InterruptedException e) {
}
}
You should create a data structure like an array to store the survey data, I would index it by group and/or child position, whatever makes sense for the data. Then you should add listeners for each question input, when a question is answered yes, add into that data structure the answer at the appropriate location. Then when you press the submit button it can iterate over that data structure, prompt for unanswered questions or fill out default values, gather it all together and then submit.
Basically there's no easy/built in way to access the individual rows of your dynamic/reusable rows that I have been able to find. When the context of which row is important I've found the best way is to have my own data structure that uses the group/child position to find which button is being pressed since every row has a button with the same id. I also store the group position/index in the button using setHint on creation so that in the context of the listener i can determine the position.
I had to do this via a horrific hack-job, but it works. I added a button for each row that will allow the user to "save" the row. When they save the row then the data is saved to my data structure. Unfortunately to get this working properly I had to create a custom OnClickListener which takes the view as an argument and from there I can scrape the elements from the view.
It's not an elegant or good solution; but it works.
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.
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've created a countdown timer that counts Days:Hrs:Mins:Sec. using regular text view and updating it using my handler works fine for me.
however I want to create a cool animation for the changing digits:
1st Q:
I have 2 options as I see it to draw the numbers:
1. using a home made font applied with a style
2. using a textview/btn with no text on them and applying a backrgound image using setBackgroundResource()
--what should I choose?
2nd Q:
I've created a wrapper for ViewFlipper(not extending it)
public class transitionair extends Activity {
SpecialFlipperWrapper m_thousand;
SpecialFlipperWrapper m_hundred;
SpecialFlipperWrapper m_tens;
SpecialFlipperWrapper m_ones;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ViewFlipper flipper_Tsnds=(ViewFlipper)findViewById(R.id.yearThousand);
m_thousand = new SpecialFlipperWrapper(flipper_Tsnds, this, 9);
ViewFlipper flipper_Hndrds=(ViewFlipper)findViewById(R.id.yearHundread);
m_hundred = new SpecialFlipperWrapper(flipper_Hndrds, this, 9);
ViewFlipper flipper_Tns=(ViewFlipper)findViewById(R.id.yearTens);
m_tens = new SpecialFlipperWrapper(flipper_Tns, this, 9);
ViewFlipper flipper_Ons=(ViewFlipper)findViewById(R.id.yearOnes);
m_ones = new SpecialFlipperWrapper(flipper_Ons, this, 9);
m_thousand.startFlipping();
m_hundred.startFlipping();
m_tens.startFlipping();
m_ones.startFlipping();
}
}
however trying to fetch one of the latter views that come after the yearThousand id are retrieving null
XML I'm Using is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ViewFlipper
android:id="#+id/yearThousand"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ViewFlipper
android:id="#+id/yearHundread"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ViewFlipper
android:id="#+id/yearTens"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ViewFlipper
android:id="#+id/yearOnes"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
ps xml's for the animation itself are working so I left them out
Main questions is: can I make it better?
second question is: how?
third question is why is my layout returning null on the second call to it and how can I avoid it?
10XX
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.