build layout at runtime android - android

i have a complex xml layout which has list views..a row in the list view contains several text fields which are spaced evenly. i am using textview to store the text and then finally add all the items to the row...its working perfectly fine.
but now i have case where in i am not sure, how many text fields i might get from a webservice. therefore i need to create the textview dynamically on run time, populate them and then insert into the list..
is there anyway to declare,add and populate new textview fields on runtime?
or is there is anyway to implement the spacing between the two fields?
result of first call
__________________________
|_____|_____|_____|______|
result of second call
________________________________
|_____|_____|_____|______|______|
I tried implementing the solution that was provided below (Kenny), but for some reason I am unable to add views into the list.. below is my code
public class HeaderAdapter extends ArrayAdapter<Header> {
final Header[] listSymbols;
private TextView textView;
private LinearLayout row;
public HeaderAdapter(Context context, int symResourceID,
Header[] objects) {
super(context, symResourceID, objects);
listSymbols = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.header_view, parent, false);
Header headerRec = listSymbols[position];
for(int i = 0 ; i < listSymbols.length;i++){
textView = new TextView(getContext());
textView.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, //Width of the view
ViewGroup.LayoutParams.WRAP_CONTENT));//Height of the view
textView.setId(i);
row.add??
}
}
The main activity that calls this
setContentView(R.layout.main);
headerList.add(new Header("Symbol","Quantity","Price","Price Yesterday","52 Week High","52 Week Low","Change","Days Gain","Days Gain %","Returns"));
Header[] tmpHeaderList = headerList.toArray(new Header[headerList.size()]);
ArrayAdapter<Header> headerAdapter = new HeaderAdapter(this,R.layout.twoway_header_view,tmpHeaderList);
headerListView.setAdapter(headerAdapter);
xml layout file..the main file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical">
<HorizontalScrollView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:scrollbars="none"
android:id="#+id/headerHv">
<ListView android:id="#+id/header_listView1"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#color/white" android:cacheColorHint="#00000000"
android:smoothScrollbar="true" android:scrollbars="none" />
</HorizontalScrollView>
</LinearLayout>
the file in which the template for the row is defined
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView android:id="#+id/headerList" android:layout_width="80dp"
android:layout_height="wrap_content" android:textColor="#000000"
android:typeface="sans" android:textStyle="normal" />
</LinearLayout>

Here is the way i dynamically generate custom buttons from a list, you could do the same thing with textViews:
//Setup Buttons
layout = (LinearLayout)findViewById(R.id.layoutBars);
int count = lBars.size();
for(int i = 0; i< count;i++){
final Bar b = lBars.get(i);
BarButton button = new BarButton(DDTBars.this, R.drawable.barsmall , b.getName().toUpperCase());
button.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
button.setId(i);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//Run activity passing name of the bar to retrieve data
Intent i = new Intent(DDTBars.this, DDTBar.class);
i.putExtra("name", b.getName());
startActivity(i);
}
});
layout.addView(button);
}
So you could try:
//Setup TextViews
layout = (LinearLayout)findViewById(R.id.mylayout);
int count = myTextList.size();
for(int i = 0; i< count;i++){
TextView txtView = new TextView(this);
txtView.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, //Width of the view
ViewGroup.LayoutParams.WRAP_CONTENT));//Height of the view
txtView.setId(i);
layout.addView(txtView);
}

You could do it in code. Declare TextView 's in a loop and use RelativeLayout to position them wrt each other.

Related

DB results into a ListView, data may vary

Hi a bit new to java/android programming, I am trying to populate a listview from a database. The problem is the database output for each record may have varying results. To give you an idea I have the following layout in my xml for the listview;
<?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"
android:background="#a28d7a">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/coreHeader"
android:textColor="#ffffff"
android:padding="4dp" />
<LinearLayout
android:id="#+id/coreLinear"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/coreStatsLeft"
android:textColor="#ffffff" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/textView"
android:textColor="#ffffff"
android:textAlignment="textEnd"
android:gravity="right" />
</LinearLayout>
</LinearLayout>
The first TextView is the header of sorts, bigger font, etc.. in this area it will hold two fields from the database, the NAME and the LEVEL e.g; SPIDER-MAN (Lvl 5).
The two textfields below it will hold the stats, this area can have more than one for example;
Name Value
------------------------------------
Armor 10%
Speed 5%
... and so on
Each record can be different, some may not have speed, some may not have armor... Maybe this is too difficult to do via ListView, but I need it to be searchable and I do not know what other options I have available for this.
My database fields are as follows:
Id, Name, Level, Stats
an example of the populated db would read;
1, Spider-Man, 5, 3|10%;5|5%;6|3%
I created a example to show how to add variable data to each row in a listview.
This is the Activity implementation:
public class MainActivity extends AppCompatActivity
{
private DynamicAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Simulating variable data per row. Array Adapter instead Cursor Adapter for simplicity
final DataRow[] data =
{
new DataRow("Spider Man", new String[] {"3|10%", "5|25%"}),
new DataRow("Spider Man Brother", new String[] {"3|20%"}),
new DataRow("Other Spider Man", new String[] {"3|22%", "1|12%", "4|7%"})
};
// Assign data to adapter
adapter = new DynamicAdapter(this, data);
// Getting reference to ListView
ListView listViewData = (ListView) findViewById(R.id.listViewData);
// Setting adapter to listView
listViewData.setAdapter(adapter);
}
}
This is how the Adapter will put the data for each row:
public class DynamicAdapter extends ArrayAdapter<DataRow>
{
private final Context context;
private final DataRow[] data;
public DynamicAdapter(Context context, DataRow[] data)
{
super(context, R.layout.row_layout, data);
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.row_layout, parent, false);
// Get a listview reference
LinearLayout linearLayoutRow = (LinearLayout) rowView.findViewById(R.id.coreLinear);
if(position < data.length)
{
// Put text on header
TextView textHeader = (TextView) rowView.findViewById(R.id.coreHeader);
// Set the header for this row
textHeader.setText(data[position].GetHeader());
// Creating a vertical linear layout to put the data row
LinearLayout linearLayoutData = new LinearLayout(context);
linearLayoutData.setOrientation(LinearLayout.VERTICAL);
// Get column amount for this row.
int columnAmount = data[position].GetColumnsSize();
for(int i = 0; i < columnAmount; i++)
{
// Creating dynamically a TextView for this column.
TextView dynamicData = new TextView(context);
dynamicData.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT));
// Adding data to TextView
dynamicData.setText(data[position].GetDataAt(i));
// Adding TextView to linearLayout
linearLayoutData.addView(dynamicData);
}
// Adding LinearLayout to LinearLayout on XML
linearLayoutRow.addView(linearLayoutData);
}
return rowView;
}
}
This is the full demo on Github: https://github.com/deinier/DynamicDataOnListView
I hope this help.

Handling Dynamically added Table Rows xml Layout in TableLayout Android

I have a TableLayout in fragment with following code:
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/projectsTableLayout"
android:orientation="vertical"
android:layout_margin="10dp">
</TableLayout>
This is the AddMore button which is below the TableLayout tag:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="?android:attr/buttonBarButtonStyle"
android:id="#+id/add_more_projects_btn"
android:text="#string/addmore"
android:textColor="#color/colorAccent"
android:layout_below="#+id/projectsTableLayout"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"/>
Also I have created TableRow layout in separate xml file with following code:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_weight="1"
android:orientation="vertical">
<EditText
android:id="#+id/project_name__ET"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:hint="#string/projectnametxt"
android:inputType="text"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<LinearLayout
android:id="#+id/yearProjectTypeLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="05dp"
android:orientation="horizontal"
android:weightSum="1">
<Spinner
android:id="#+id/yearSpinner"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:drawSelectorOnTop="false"
android:spinnerMode="dropdown" />
<Spinner
android:id="#+id/projectTypeSpinner"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:drawSelectorOnTop="false"
android:spinnerMode="dropdown" />
</LinearLayout>
</LinearLayout>
</TableRow>
What I want to implement is when the application loads I will be dynamically add rows 5 times.
I want to add 5 more rows on the Add More button click. Also I have to send all the values to the webserver when the user moves ahead in the application.
I am confused how should provide the ID to the components like(EditText, Spinners) in the Rows of table and retrieve it when the user moves to next screen.
I want to code in such a way so it can be optimised and easy to retrieve all the data for as many rows added to TableLayout on the AddMore Button click.
How to retrieve values and set ids for Row Components.
EDIT ::
Modification of code as suggested by #Rohit Heera
I have written following code:
projectTableLayout = (TableLayout) rootView.findViewById(R.id.projectsTableLayout);
projectTableLayout.setStretchAllColumns(true);
yearAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_dropdown_item, Constants.YEAR_ARRAY);
projectTypeAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_dropdown_item, Constants.PROJECT_TYPE_ARRAY);
projectListData = new ArrayList<ProjectData>();
for(int i = 0; i < 5 ; i++)
{
tableRowStartCount = i;
TableRow projectItemRow = new TableRow(getActivity().getApplicationContext());
LayoutInflater inflator = (LayoutInflater) getActivity().getSystemService(getActivity().getApplicationContext().LAYOUT_INFLATER_SERVICE);
projectItemRow.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.MATCH_PARENT, 1.0f));
View projectRowView = inflator.inflate(R.layout.project_row_item,projectItemRow,false);
projectNameET = (EditText) projectRowView.findViewById(R.id.project_name__ET);
yearSpinner = (Spinner) projectRowView.findViewById(R.id.yearSpinner);
yearSpinner.setAdapter(yearAdapter);
projectTypeSpinner = (Spinner) projectRowView.findViewById(R.id.projectTypeSpinner);
projectTypeSpinner.setAdapter(projectTypeAdapter);
projectItemRow.addView(projectRowView);
ProjectData projectObj = new ProjectData();
projectListData.add(projectObj);
projectTableLayout.addView(projectItemRow,tableRowStartCount);
}
Can you please let me know how can i implement the eventlistener in the above loop?
Use this code to add rows in table
/**
* this method add the dynamic table row and display the list .
*/
public void displayList(List<Data> datalist) {
int i = 0;
TableLayout projectsTableLayout = (TableLayout) findViewById(R.id.projectsTableLayout);
projectsTableLayout.removeAllViews();
for (i = 0; i <= datalist.size(); i++) {
TableRow singleTableRow = new TableRow(this);
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflator.inflate(R.layout.addattendeelistdata, null);
RelativeLayout parentRelativeLayout = (RelativeLayout) view
.findViewById(R.id.comleteRL);
EditText project_name__ET = (EditText) view
.findViewById(R.id.project_name__ET);
Spinner yearSpinner = (Spinner) view
.findViewById(R.id.yearSpinner);
Spinner projectTypeSpinner = (Spinner) view
.findViewById(R.id.projectTypeSpinner);
singleTableRow.addView(view);
/** Add row to TableLayout. */
projectsTableLayout.addView(singleTableRow, i);
}
}
And for get Reference for each object you need to Create seperate class .
If you tell me on which event you can move to next class so i can help you better.
Thanks
Like Edit Text you need to create separte class for spinner item listeners and store the value and main list automatically get all the new values.
/**
* this method add the dynamic table row and display the list .
*/
List<ProjectData> mainList=new List<ProjectData>();
// calling function
displayList(mainList);
public void displayList(List<ProjectData> datalist) {
int i = 0;
TableLayout projectsTableLayout = (TableLayout) findViewById(R.id.projectsTableLayout);
projectsTableLayout.removeAllViews();
for (Iterator<ProjectData> it :datalist.hasNext();) {
TableRow singleTableRow = new TableRow(this);
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflator.inflate(R.layout.addattendeelistdata, null);
RelativeLayout parentRelativeLayout = (RelativeLayout) view
.findViewById(R.id.comleteRL);
EditText project_name__ET = (EditText) view
.findViewById(R.id.project_name__ET);
Spinner yearSpinner = (Spinner) view
.findViewById(R.id.yearSpinner);
Spinner projectTypeSpinner = (Spinner) view
.findViewById(R.id.projectTypeSpinner);
project_name__ET.addTextChangedListener(new ListenEditText(it.next()) );
singleTableRow.addView(view);
/** Add row to TableLayout. */
projectsTableLayout.addView(singleTableRow, i);
}
}
class ListenEditText implements TextWatcher
{
ProjectData data;
ListenEditText(ProjectData data)
{
this.data=data;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
data.project_name=s.toString();
}}
ModelClass;
class ProjectData
{
public String project_name;
public String year;
public String projectType;
}

Inflate layout and use its child items

I have a layout where I want to imitate a listview by adding items programmatically one below the other. So I created an .xml for the layout of these items that are something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_lista"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/rellay_btn"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:text="Some name"
android:textColor="#3F3F3F"
android:textSize="17sp"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/iv_follow"
android:text="Some text"
android:textColor="#3F3F3F"
android:textSize="13sp" />
</LinearLayout>
In the activity I would like to generate n of this layout, fill the textviews with text and also I would like to set an onClickListener on them. n is the size of an array. Please help
Note: Once the activity loads, the number of layouts will not change, nor can a layout be removed.
This is what I have now but the layout is displayed on top of the activity instead of below a Textview:
LayoutInflater inflater = LayoutInflater.from(BucketProfileActivity.this);
for (int i = 0; i < 3; i++) {
View view = inflater.inflate(R.layout.bucketprofile_tips, null);
view.setId(i);
TextView tv_username = (TextView) view.findViewById(R.id.tv_username);
tv_username.setText(String.valueOf(i));
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
rl.addRule(RelativeLayout.BELOW, R.id.tv_nemkell);
addContentView(view, rl);
}
If your posted xml file is bucketprofile_tips.xml then you need to change here from
TextView tv_username = (TextView) view.findViewById(R.id.tv_title);
to
TextView tv_username = (TextView) view.findViewById(R.id.tv_username);
Because in bucketprofile_tips.xml tv_title id not found for your TextView. So you are getting Null Pointer Exception.
Not sure why you would want to do this but you can just use a LayoutInflater to inflate x of this view and add them to a designated ViewGroup. For example:
LayoutInflater inflater = LayoutInflater.from(context);
for (int i = 0; i < numberOfViews; i++) {
View v = inflater.inflate(R.layout.view_to_add, parentView, false);
setup(v);
parentView.addView(v);
}
Where setup() is a function you define that does the setup work such as setting the text of a TextView etc.
For instance, in your setup function might look something like this:
private void setup(View v) {
TextView tv = (TextView) v.findViewById(R.id.name);
// set the text of the text view
tv.setText("Hello!");
// set the click listener for the view...
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// do stuff here...
}
});
}
LinearLayout parentLayout=findViewById(R.id.parentLayout);
LayoutInflater inflater = LayoutInflater.from(BucketProfileActivity.this);
View view = inflater.inflate(R.layout.bucketprofile_tips, null);
parentLayout.addView(view);
LinearLayout textList=(LinearLayout) parentLayout.getChildAt(0);
for(int i=0; i<textList.getChildCount(); i++){
TextView tv_username=(TextView) textList.getChildAt(i);
textView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
tv_username.setText(String.valueOf(i));
}
}
}

Dynammically create ImageViews not showing the image

I have a custom adapter for a listview and here is the getView method;
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
LayoutInflater inflater = (LayoutInflater) JourneyPlannerActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.journey_planner_route_detail, viewGroup, false);
LinearLayout layout = (LinearLayout) rowView.findViewById(R.id.journey_planner_detail_detail_main_id);
JourneyPlannerRoute r = m_Routes.get(i);
String directions = "";
for(int j=0 ; j < r.getRoutes().size() ; j++){
ImageView image = new ImageView(JourneyPlannerActivity.this);
String transportMethod = r.getRoutes().get(j).getMeansOfTransport();
if(transportMethod.equals("Train"))
image.setImageResource(R.drawable.network_rail_logo);
else if(transportMethod.equals("Subway"))
image.setBackgroundResource(R.drawable.roundel_tube);
else if(transportMethod.equals("Bus"))
image.setBackgroundResource(R.drawable.bus);
else if(transportMethod.equals("Walk"))
image.setBackgroundResource(R.drawable.walking);
image.setVisibility(View.VISIBLE);
layout.addView(image);
//directions += r.getRoutes().get(j).getMeansOfTransport()+",";
}
directions += " "+r.getDuration();
TextView tv = (TextView) rowView.findViewById(R.id.journey_planner_detail_main_text_view);
tv.setText(directions);
return rowView;
After going through the debug it seems the imageviews are being added to the layout but they're just not appearing on the screen;
I had a feeling it was due to not picking up the correct layout but it seems as though it is?!
Here is the xml file for the row;
<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:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/journey_planner_detail_detail_main_id">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/bus_small"/>
<TextView
android:id="#+id/journey_planner_detail_main_text_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
Instead of creating new Image view just call rowView.findViewById(R.id.image_id); (you'll have to add id to the xml).
The actual bug is with the TextView. It is set to fill_parent causing the newly added ImageView to appear to the right of the visible screen. You can change this by changind the TextView width to wrap_content. However, using the ImageView defined in xml layout is better.

Android: button showing up multiple times in list view

I trying to write code to highlight the selected value of the list with "Next" button at the bottom of the layout. But for some reason, after every list item, "next" button also shows up. Can someone please help me resolve this problem?
Here is the layout file:
<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:orientation="vertical"
android:id="#+id/questionLayout"
>
<TextView android:id="#+id/txtExample"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textColor="#000000"
android:background="#FF0000"
/>
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<Button
android:id = "#+id/next"
android:text="Next"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:layout_gravity="center"
android:layout_weight="50"
/>
<Button
android:id = "#+id/submit"
android:text="Submit"
android:layout_width = "0dp"
android:layout_height = "wrap_content"
android:layout_weight="50"
android:layout_gravity="center"
/>
</LinearLayout>
</LinearLayout>
Java Code:
public class updateList extends Activity {
private SelectedAdapter selectedAdapter;
private ArrayList<String> list;
int correct_answer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<String>();
list.add("Choice One");
list.add("Choice Two");
list.add("Choice Three");
selectedAdapter = new SelectedAdapter(this,0,list);
selectedAdapter.setNotifyOnChange(true);
ListView listview = (ListView) findViewById(R.id.listExample);
listview.setAdapter(selectedAdapter);
listview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view,
int position, long id) {
// user clicked a list item, make it "selected"
selectedAdapter.setSelectedPosition(position);
}
});
}
}
Thanks in advance
SSP
Selected Adaptor class:
public class SelectedAdapter extends ArrayAdapter{
// used to keep selected position in ListView
private int selectedPos = -1; // init value for not-selected
public SelectedAdapter(Context context, int textViewResourceId,
List objects) {
super(context, textViewResourceId, objects);
}
public void setSelectedPosition(int pos){
selectedPos = pos;
// inform the view of this change
notifyDataSetChanged();
}
public int getSelectedPosition(){
return selectedPos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// only inflate the view if it's null
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.activity_main, null);
}
// get text view
TextView label = (TextView)v.findViewById(R.id.txtExample);
// change the row color based on selected state
if(selectedPos == position){
label.setBackgroundColor(Color.CYAN);
}else{
label.setBackgroundColor(Color.WHITE);
}
label.setText(this.getItem(position).toString());
/*
// to use something other than .toString()
MyClass myobj = (MyClass)this.getItem(position);
label.setText(myobj.myReturnsString());
*/
return(v);
}
}
change your listview in xml as like this
<ListView
android:id="#+id/listExample"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"//===== set maximum heighthere
android:layout_marginBottom="50dp"// === give some space at bottom so that buttons will appear
android:background="#CCCCCC"
android:choiceMode="singleChoice"
/>
But for some reason, after every list item, "next" button also shows up.
The ListView's row layout is determined by the layout you inflate in getView() or pass to your Adapter's super class if you haven't overridden getView(). Double check this layout and remove the unwanted code.
Addition
The layout for your ListView's items only needs to be one TextView since you only want to display a phrase in each. However you are currently passing your entire main layout, this creates the Buttons, an unused ListView, and everthing else in every row...
Instead use android.R.layout.simple_list_item_1 in getView(), of course you'll need to change the id you pass to findViewById() as well:
if (v == null) {
LayoutInflater vi = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(android.R.layout.simple_list_item_1, null);
}
// get text view
TextView label = (TextView)v.findViewById(android.R.id.text1);
Please watch Android's Romain Guy discuss writing an efficient adapter to speed things up.

Categories

Resources