ListView not displaying on inflate - android

I have a TableLayout that has it's rows populated dinamically via database. On each row, I'm trying to make a OnLongClickListener() to show a ListView from a different .xml than my activity_product.xml. Here is relevant part of code from my activity_product.xml:
<TableLayout
android:id="#+id/productsTable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="3dip"
android:paddingRight="3dip"
android:shrinkColumns="1"
android:weightSum="1"
android:stretchColumns="*">
</TableLayout>
And here is my edit_or_delete_menu.xml with the ListView
<?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" >
<ListView
android:id="#+id/edirOrDeleteMenu"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
And here is the relevant part of the code I use to populate the rows and attempt to show the ListView:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product);
new LoadProductsTableContent().execute();
}
private class LoadProductsTableContent extends AsyncTask<Void, Void, Integer> {
private TableLayout productsTable = (TableLayout) findViewById(R.id.productsTable);
private TableRow labelRow = (TableRow) findViewById(R.id.productLabelsRow);
#Override
protected Integer doInBackground(Void... params)
{
int result=1;
// Usado para acessarmos as views da thread pai
// http://stackoverflow.com/questions/5161951/android-only-the-original-thread-that-created-a-view-hierarchy-can-touch-its-vi
runOnUiThread(new Runnable() {
#Override
public void run() {
// Create a new row to be added
TableRow tr = new TableRow(ProductActivity.this);
/* CODE TO SET ROW PROPERTIES AND CONTENT */
// Row click listener
tr.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
onClickRow(v);
return false;
}
});
// Add row to TableLayout
productsTable.addView(tr);
}
});
return result;
}
private void onClickRow(View v) {
String editText = getResources().getString(R.string.menuEditOption);
String deleteText = getResources().getString(R.string.menuDeleteOption);
// Inflating to display ListView
LayoutInflater inflater = (LayoutInflater) ProductActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.edir_or_delete_menu, null);
edirOrDeleteMenu = (ListView) v.findViewById(R.id.edirOrDeleteMenu);
String[] options = new String[]{editText, deleteText};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ProductActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, options);
edirOrDeleteMenu.setAdapter(adapter);
}
The code compiles and no error happens when executing this code, but my ListView doesn't show up. What am I missing here?
Thanks in advance.

I guess the problem is here:
LayoutInflater inflater = (LayoutInflater) ProductActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.edir_or_delete_menu, null);
You inflated a view, but didn't add it anywhere. Add it as a child view to the view which is supposed to be its parent.
Also you need to declare and assign the inflater.inflate(...) result to another variable instead of v. The v is the view, which is clicked. Create a new variable and then add it as a child, as I wrote above.
Something like this:
LayoutInflater inflater = (LayoutInflater) ProductActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.edir_or_delete_menu, null);
v.addView(view);

Related

Creating a table layout with column depends on spinner in Android

I want to create a table that the columns'text depends on spinner. Later to add the row, i can color the specified cell. It looks like this : http://tinypic.com/view.php?pic=2j639xf&s=8#.U-mRRpD-Lcs
That example is landscape because i develop it on dekstop, so i want a table like that as portait in android.
The problem is :
1. when i run it on device, the spinner is gone
2. I don't know yet how to color each cell in the table. Or should I make a new question?
Here's my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reservation_schedule);
Spinner spinnerFacility = (Spinner)findViewById(R.id.spinnerFacility);
ArrayList<String> alTop = getTimeTableColumnTop((int)spinnerFacility.getSelectedItemId());
String[] column = alTop.toArray(new String[alTop.size()]);
ArrayList<String> alLeft = getTimeTableColumnLeft();
String[] row = alLeft.toArray(new String[alLeft.size()]);
int rl=row.length+1; int cl=column.length+1;
Log.d("--", "R-Lenght--"+rl+" "+"C-Lenght--"+cl);
ScrollView sv = new ScrollView(this);
TableLayout tableLayout = createTableLayout(row, column,rl, cl);
HorizontalScrollView hsv = new HorizontalScrollView(this);
hsv.addView(tableLayout);
sv.addView(hsv);
setContentView(sv);
}
private ArrayList<String> getTimeTableColumnTop(int facilitySelectedIndex)
{
ArrayList<String> timeTableColumnTop = new ArrayList<String>();
if(facilitySelectedIndex == 0)
{
timeTableColumnTop.add("Discuss Room 1");
timeTableColumnTop.add("Discuss Room 2");
timeTableColumnTop.add("Discuss Room 3");
}else
{
timeTableColumnTop.add("Pri-View 1");
timeTableColumnTop.add("Pri-View 2");
timeTableColumnTop.add("Pri-View 3");
timeTableColumnTop.add("Pri-View 4");
timeTableColumnTop.add("Pri-View 5");
}
return timeTableColumnTop;
}
private ArrayList<String> getTimeTableColumnLeft()
{
ArrayList<String> timeTableColumnLeft = new ArrayList<String>();
for(int i = 8 ; i<17; i++)
{
timeTableColumnLeft.add(i+":00");
}
return timeTableColumnLeft;
}
For the function createTableLayout(row,column,rl,cl); i use the code from http://www.prandroid.com/2014/05/creating-table-layout-dynamically-in.html
The activity_reservation_schedule.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="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/reservation_spinner_facility_prompt"/>
<Spinner
android:id="#+id/spinnerFacility"
android:prompt="#string/reservation_spinner_facility_prompt"
android:entries="#array/reservation_facility_entries"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Here is strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ReservationTab(Schedule)</string>
<string name="reservation_spinner_facility_prompt">Pick a facility</string>
<string-array name="reservation_facility_entries">
<item>Discussion Room</item>
<item>Private Viewing</item>
</string-array>
</resources>
Note : i'm new on Android, i'm using eclipse. This is my first post here, please excuse my english. Any suggestion is appreciated, thanks.
Few points:
If i understood you correctly,
You need to "add" the scroll view to your root view linearlayout.
Add a Custom Item Selected listener for Spinner and change layout depending on selection
e.g
Sample Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ll = (LinearLayout)findViewById(R.id.ll);
Spinner spinnerFacility = (Spinner)findViewById(R.id.spinnerFacility);
spinnerFacility.setOnItemSelectedListener(new CustomOnItemSelectedListener());
// more of your code.....
ll.addView(sv) // instead of setContentView(sv)
public class CustomOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
Toast.makeText(parent.getContext(),
"OnItemSelectedListener : " + parent.getItemAtPosition(pos).toString(),
Toast.LENGTH_SHORT).show();
ll.removeView(sv);
ArrayList<String> alTop = getTimeTableColumnTop(pos);
String[] column = alTop.toArray(new String[alTop.size()]);
ArrayList<String> alLeft = getTimeTableColumnLeft();
String[] row = alLeft.toArray(new String[alLeft.size()]);
int rl=row.length+1; int cl=column.length+1;
Log.d("--", "R-Lenght--"+rl+" "+"C-Lenght--"+cl);
sv = new ScrollView(getApplicationContext());
TableLayout tableLayout = createTableLayout(row, column,rl, cl);
HorizontalScrollView hsv = new HorizontalScrollView(getApplicationContext());
hsv.addView(tableLayout);
sv.addView(hsv);
ll.addView(sv);
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
}

Generate background colour in listView from database

I have a listView generated from a database, is there a way to make a background colour or a picture to each "section" in the list:
if the first symbol in "Tip" is "W" the background should be Green, and if its "L" it should be red
Im thinking something like this, but i have no idea where to put it since it have to be done in every section:
tipvalue = BetsDbAdapter.KEY_TIP;
//Here to split the value to gain only "W" or "L"
String arrtip[] = tipvalue.split(" ", 2);
temptip = arrtip[0];
//then set background
if (temptip.equals("W")) {
getWindow().getDecorView().setBackgroundColor(Color.GREEN);
To the left is my listView and right is the xml file to make each "section" in the listview
Here is my database:
This is code generating the listView
public class StoredBets extends Activity {
private BetsDbAdapter dbHelper;
private SimpleCursorAdapter dataAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.results);
dbHelper = new BetsDbAdapter(this);
dbHelper.open();
}
#Override
public void onStart(){
super.onStart();
displayListView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.results, menu);
return true;
}
public void testknap1(View v) {
Intent myIntent = new Intent(StoredBets.this, Overview.class);
startActivity(myIntent);
}
private void displayListView() {
Cursor cursor = dbHelper.fetchAllStats();
String[] columns = new String[] {
BetsDbAdapter.KEY_SMATCH,
BetsDbAdapter.KEY_TIP,
BetsDbAdapter.KEY_BETAMOUNT,
BetsDbAdapter.KEY_BODDS
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.smatch,
R.id.tip,
R.id.bodds,
R.id.betamount,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.storedbets,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView2);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long id) {
// Get the cursor, positioned to the corresponding row in the result set
Cursor cursor = (Cursor) listView.getItemAtPosition(position);
// Get the state's capital from this row in the database.
String betMatch =
cursor.getString(cursor.getColumnIndexOrThrow("smatch"));
Toast.makeText(getApplicationContext(),
betMatch, Toast.LENGTH_SHORT).show();
Intent myIntent = new Intent(StoredBets.this, SetWinVoidLoss.class);
myIntent.putExtra("id", id);
startActivity(myIntent);
}
});
}
}
EDIT 2:
#amal
This is the layout(results.xml) with the listview
<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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".StoredBets" >
<ListView
android:id="#+id/listView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_alignTop="#+id/button1" >
</ListView>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="180dp"
android:onClick="testknap1"
android:text="Button" />
</RelativeLayout>
you can get a fair idea from my code,
code snippet for displaying ListViews where the "curSelected" item has a different background:
final ListView lv = (ListView)findViewById(R.id.lv);
lv.setAdapter(new BaseAdapter()
{
public View getView(int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = new TextView(ListHighlightTestActivity.this);
convertView.setPadding(10, 10, 10, 10);
((TextView)convertView).setTextColor(Color.WHITE);
}
convertView.setBackgroundColor((position == curSelected) ?
Color.argb(0x80, 0x20, 0xa0, 0x40) : Color.argb(0, 0, 0, 0));
((TextView)convertView).setText((String)getItem(position));
return convertView;
}
public long getItemId(int position)
{
return position;
}
public Object getItem(int position)
{
return "item " + position;
}
public int getCount()
{
return 20;
}
});
This is a tutorial of how to write an adapter for a list view. amal is right, you can change the separate items in the list view in the getView() method.

Showing graphical instead of strings in an imagelist with title

At the moment I am getting items out of my database and add them to a string called result which I return and set to my TextView:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.level);
loadDataBase();
int level = Integer.parseInt(getIntent().getExtras().getString("level"));
questions = new ArrayList<Question>();
questions = myDbHelper.getQuestionsLevel(level);
tvQuestion = (TextView) findViewById(R.id.tvQuestion);
i = 0;
String data = getAllItems();
tvQuestion.setText(data);
}
private String getAllItems() {
result = "";
for (i = 0; i<9; i++){
result = result + questions.get(i).getQuestion() + "\n";
}
return result;
// TODO Auto-generated method stub
}
The thing is, all these items also have a title(string) and graphical thumb (string) in the database. I would like to show them as illustrated in the picture below, each with an onclicklistener on it, instead of a boring list of items below eachother. Each item has a picture and title.
Since my beginning programming skills, I am wondering how to do this best, and if you know any good tutorials on it which explain it well?
Thanks!
if i understood your question you need to create a customize an adapter.
Create a new simple class like this which holds an string and a picture
Class ObjectHolder {
int Image;
String Title;
}
and create a getter and setter for this two
then create custom ArrayAdapter
Class CustomArrayAdapter extends ArrayAdapter<ObjectHolder> {
public CustomArrayAdapter(Context C, ObjectHolder[] Arr) {
super(C, R.layout.caa_xml, Arr);
}
#Override
public View getView(int position, View v, ViewGroup parent)
{
View mView = v ;
if(mView == null){
LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = vi.inflate(R.layout.cpa_xml, null);
}
TextView text = (TextView) mView.findViewById(R.id.tv_caarow);
ImageView image = (ImageView) mView.findViewById(R.id.iv_caarow);
if(mView != null )
{ text.setText(getItem(position).getText());
image.setImageResource(getItem(position).getImage());
return mView;
}
}
and create caa_xml.xml in res\layout\
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/iv_caarow"
android:src="#drawable/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tv_caarow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="15dip"
android:layout_BottomOf="#+id/iv_caarow" />
</RelativeLayout>
and use it like this.
GridView GV= (GridView) findViewById(R.Id.gv); // reference to xml or create in java
ObjectHolder[] OHA;
// assign your array, any ways!
mAdapter CustomArrayAdapter= CustomArrayAdapter(this, OHA);
GridView.setAdapter(mAdapter);

How do I dynamically update a spinner using ArrayList?

I have created a Spinner that is populated with an ArrayList. I want to dynamically add values to the ArrayList, so the the Spinner populates dynamically. However, when I try to add values to my ArrayList, I get a NullPointerException.
What am I missing? Do I have to reset the adapter before amending the ArrayList?
Here is my code:
My spinner, arraylist, and adapter:
deleteselection = (Spinner)view.findViewById(R.id.deletespinner);
portfoliosdelete = new ArrayList<String>();
portfoliosdelete.add("Select Portfolio");
adapterdeletetype = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,portfoliosdelete){
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View v = null;
// If this is the initial dummy entry, make it hidden
if (position == 0) {
TextView tv = new TextView(getContext());
tv.setHeight(0);
tv.setVisibility(View.GONE);
v = tv;
}
else {
// Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent);
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.setVerticalScrollBarEnabled(false);
return v;
}
};
adapterdeletetype.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
deleteselection.setAdapter(adapterdeletetype);
My code to dynamically update spinner:
else if(users.contains(usernull)){
pn1 = enterportfolioname.getText().toString();
user1 = new PortfolioRecord(pn1, "someemail#gmail.com");
users.remove(usernull);
users.add(user1);
portfoliosdelete.add(pn1); // <-- This causes a null pointer exception
adapterdeletetype.notifyDataSetChanged();
portfoliolist.invalidateViews();
Use the code below. This code will add a new item when the user selects and add a new item from the spinner.
Code sample:
layout main.xml:
<?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"
android:weightSum="10" >
<Spinner
android:id="#+id/cmbNames"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
layout spinner_item.xml
<?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" >
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Activity class:
public class MainActivity extends Activity {
private static final String NAME = "name";
private static final String ADD_NEW_ITEM = "Add New Item";
private SimpleAdapter adapter;
private Spinner cmbNames;
private List<HashMap<String, String>> lstNames;
private int counter;
private OnItemSelectedListener itemSelectedListener = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
HashMap<String, String> map = lstNames.get(arg2);
String name = map.get(NAME);
if (name.equalsIgnoreCase(ADD_NEW_ITEM)) {
lstNames.remove(map);
counter++;
addNewName(String.valueOf(counter));
addNewName(ADD_NEW_ITEM);
adapter.notifyDataSetChanged();
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
populateList();
cmbNames = (Spinner) findViewById(R.id.cmbNames);
adapter = new SimpleAdapter(this, lstNames, R.layout.spinner_item,
new String[] { NAME }, new int[] { R.id.tvName });
cmbNames.setAdapter(adapter);
cmbNames.setOnItemSelectedListener(itemSelectedListener);
}
private void populateList() {
lstNames = new ArrayList<HashMap<String, String>>();
addNewName("abc");
addNewName("pqr");
addNewName("xyz");
addNewName(ADD_NEW_ITEM);
}
private void addNewName(String name) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(NAME, name);
lstNames.add(map);
}
}
Try to call delete on adapterdeletetype instead of the arraylist. If it fails, then please post your logcat output.

Android custom listview

Hi i've got a custom listview with a text view and a button in each row.
Im having trouble trying to use the buttons . Each button will fire a different intent. This is the xml file for the list view rows.
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
android:id="#+id/widget28"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<Button
android:id="#+id/widget29"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Remind me"
android:layout_alignParentRight="true"
/>
<TextView android:id="#+id/text12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff99ccff"
android:text="Text view" />
</RelativeLayout>
Then i have another xml file which simply contains the list view in a linear layout.
This is my custom array class.
public class customArray extends ArrayAdapter<String> {
int resource;
public customArray(Context cont, int _resource, List<String> items) {
super (cont, _resource,items);
resource = _resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RelativeLayout rl;
String prod = getItem(position);
if (convertView == null) {
rl = new RelativeLayout(getContext());
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi.inflate(resource, rl, true);
} else {
rl = (RelativeLayout)convertView;
}
TextView t1 = (TextView)rl.findViewById(R.id.text12);
t1.setText(prod);
Button b1 = (Button)rl.findViewById(R.id.widget29);
return rl;
}
}
Then the final class which gets the data from a database and uses the custom adapter to display the information. Does anyone know how i would call each button?
`public class SatMain extends Activity {
/** Called when the activity is first created.
* #param cont */
#Override
public void onCreate(Bundle savedInstanceState)
{
List<String> results = new ArrayList<String>();
super.onCreate(savedInstanceState);
setContentView(R.layout.satmain);
dbAdapter db = new dbAdapter(this);
// button.setOnClickListener(m);
//---get all titles---
db.open();
db.InsertData();
Cursor c = db.getSat1();
if (c.moveToFirst())
{
do {
String pub = c.getString(c.getColumnIndex(db.KEY_Artist));
String pub1 = c.getString(c.getColumnIndex(db.KEY_Time));
results.add(pub + pub1 );
} while (c.moveToNext());
}
db.close();
ListView listProducts;
customArray ca = new customArray(this, R.layout.button, results);
listProducts = (ListView)findViewById(R.id.list1);
listProducts.setAdapter(ca);
ca.notifyDataSetChanged();
}
}`
In the "getView" method of your adapter, you should set an onClick listener for the button. You can do an anonymous class so that you can refer to the contents of the row in the button. I.e, add the following where you get b1 in your example.
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//create activity based on prod
}
});

Categories

Resources