I have a TableLayout to which I am adding table row with the below configuration dynamically.
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="4dp"
>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/name"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="left"/>
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/colon"
android:padding="10dip"/>
<EditText
android:id="#+id/add_server_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFBFCCCC"
android:inputType="text"
android:gravity="left"
android:paddingLeft="5dp"/>
</TableRow>
The code I am using the add table row is below:
TableLayout table = (TableLayout) findViewById(R.id.create_table);
LayoutInflater inflater = getLayoutInflater();
ArrayList<String> edit_test_items = getTextFields();
if(edit_test_items!=null){
for (String item : edit_test_items) {
View row = inflater.inflate(R.layout.tbl_row_label_and_edittext,
table, false);
TextView label = (TextView) row.findViewById(R.id.textView1);
label.setText(item);
EditText value = (EditText) row.findViewById(R.id.add_server_name);
value.setTag(item);
actTextVals.add(value);
table.addView(row);
}
}
ArrayList<String> spinner_items = getSpinnerFields();
if(spinner_items!=null){
for (String item : spinner_items) {
View row = inflater.inflate(R.layout.tbl_row_label_and_spinner,
table, false);
TextView label = (TextView) row.findViewById(R.id.textView4);
label.setText(item);
Spinner spinner = (Spinner) row.findViewById(R.id.group);
spinner.setTag(item);
adapter = getSpinnerDataArray(item);
// ArrayAdapter.createFromResource(this,
// R.array.groups_array,android.R.layout.simple_spinner_item);
// set the appearance of widget items that show when open the widget
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// set the adapter to spinner
spinner.setAdapter(adapter);
// set the action listener
spinner.setOnItemSelectedListener(this);
actSpinnerVals.add(spinner);
table.addView(row);
}
}
ArrayList<String> checkbox_items = getCheckBoxFields();
if(checkbox_items!=null){
for (String item : checkbox_items) {
View row = inflater.inflate(R.layout.tbl_row_label_and_checkbox,
table, false);
TextView label = (TextView) row.findViewById(R.id.textView4);
label.setText(item);
CheckBox checkBox = (CheckBox) row.findViewById(R.id.checkbox);
checkBox.setTag(item);
actCheckBoxVals.add(checkBox);
table.addView(row);
}
}
Now when I have only about 4 items in the edit_test_items list I am getting the screen rendered properly but when I have about 10 items in the list text is getting clPlease find the screenshot below
Try setting the android:shrinkColumns="1" in your TableLayout.
I actually figured out what is wrong. I had my table layout inside linear layout. I changed it to scroll view and everything looks good.
Related
I have a spinner that allows me to not show the first item in the list, but i can set my custom prompt. However whenever the prompt text spans more than one line it is cut off at the view bounds. How can i make the spinner prompt expand to accommodate more text?
I have tried modifying the view passed into the adapter to have multiple lines and also to ellipsize at the end, but nothing works.
Images for clarity:
With one line of text,
With several lines,
This is my code:
languagesSpinner.setAdapter(new ArrayAdapter<>(EditProfileNationalityActivity.this, R.layout.no_default_spinner_item, new String[] {""}));
if(data.length>0) {
String countries = spokenLanguages.toString().substring(0, spokenLanguages.toString().length() - 2);
languagesSpinner.setPrompt(countries);
} else {
Log.e("setting prompt to default");
languagesSpinner.setPrompt("Please select languages");
}
and this is the xml file:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:textColor="#android:color/black"
android:textSize="18sp"
android:ellipsize="end"
android:lines="2"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="1dp"
android:paddingRight="1dp"
android:background="?android:attr/activatedBackgroundIndicator" />
Per request, xml definition of spinner is as follows:
<com.package.views.NoDefaultSpinner
android:id="#+id/registration_stage_4_country_languages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:clickable="false" />
NoDefaultSpinner.java can be found here: https://github.com/geftimov/android-components/blob/master/components/src/main/java/com/eftimoff/components/views/spinners/nodefault/NoDefaultSpinner.java
I have modified it to have a custom getView() method in the SpinnerProxy like this:
if (position < 0) {
if (layoutResource == -1) {
layoutResource = R.layout.no_default_spinner_item;
}
final TextView v =
(TextView) ((LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE)).inflate(
layoutResource, parent, false);
v.setText(getPrompt());
v.setPadding(0, 5, 0, 5);
return v;
}
return obj.getView(position, convertView, parent);
}
I edited your source code:
adapter = new ArrayAdapter<>(EditProfileNationalityActivity.this, R.layout.no_default_spinner_item, new String[] {""});
adapter.setDropDownViewResource(R.layout.no_default_spinner_item);
languagesSpinner.setAdapter(adapter);
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.
I want my spinner to look like this
Only the topmost header should have image and text. Remaining drop down should have text only.
Can anyone help me in making this.
I have tried this..
I my xml file
<Spinner android:id="#+id/spinner1"
android:layout_width="200dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_below="#id/view"
android:layout_marginLeft="35dp"
android:layout_marginTop="20dp"
android:background="#drawable/grey_btn"
android:popupBackground="#drawable/drop_down_background"
android:spinnerMode="dropdown" />
and then
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(mContext, R.drawable.spinner_text,R.id.customtextview,arr1); adapter1.setDropDownViewResource(R.drawable.drop_down); s1.setAdapter(adapter1);
You should have both a getView and getDropDownView in the adapter. In that way you could specify different looks on the selected item and the rest of the list.
in getView:
textView = (TextView) convertView.findViewById(R.id.spinner_item_text);
imageView = (ImageView) convertView.findViewById(R.id.spinner_item_image);
textView.setVisibility(ImageView.VISIBLE);
imageView.setVisibility(ImageView.VISIBLE);
in getDropDownView:
textView = (TextView) convertView.findViewById(R.id.spinner_item_text);
imageView = (ImageView) convertView.findViewById(R.id.spinner_item_image);
textView.setVisibility(ImageView.VISIBLE);
imageView.setVisibility(ImageView.INVISIBLE);
What i want is the Text color of the spinner should be white at runtime when it is displayed inside the Spinner as it is in spinner 1 and 2 and the text color of the list of Spinner should be black as in the picture.
The problem is i am able to do it for the first 2 Spinners but fail to do it for the 3rd and the 4th Spinner.
If you can see the 3rd and 4th Spinner has values but in black. I don't understand that if its possible for 2 spinners then y not for all 4. please help me.
This is my code to change color at runtime:
public class Text // class for changing the text color of spinner
{
private TextView tv = null;
Text(View spin_adptr)
{
tv = (TextView) spin_adptr.findViewById(R.id.textspin);
tv.setTextColor(Color.WHITE);
}
}
and this is how i am calling it:
public void onItemSelected(AdapterView<?> parent, View arg1, int position,
long arg3) {
int id = parent.getId();
Text text = new Text(spinner1); //Change of color (Working)
Text text1 = new Text(spinner3); //Change of Color(ERROR)
Text text2 = new Text(spinner4); //Change of Color(ERROR)
switch (id) {
case R.id.spinner1:
String b = spinner1.getSelectedItem().toString();
if (b != null) {
dbCarHelper.make_pop(b);
}
List<String> lb = h.getAllLabels();
ArrayAdapter<String> dAdapter = new ArrayAdapter<String>(this,
R.layout.spin_adptr,lb);
dAdapter.setDropDownViewResource(R.layout.spin_adptr);
spinner2.setAdapter(dAdapter);
break;
case R.id.spinner2:
Text text1 = new Text(spinner2); //// Change of color (working)
String a = spinner2.getSelectedItem().toString();
if (a != null) {
dbCarHelper.m_pop(a);
}
CarHelper c = new CarHelper(getApplicationContext());
List<String> lable = c.getAllLabel();
ArrayAdapter<String> dAdaptr = new ArrayAdapter<String>(this,
R.layout.spin_adptr,lable);
dAdaptr.setDropDownViewResource(R.layout.spin_adptr);
spinner3.setAdapter(dAdaptr);
break;
}
}
make a xml file named as spinner_layout and write code as below
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerItemStyle"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:paddingLeft="4dp"
android:textSize="18sp"
android:textColor="#FFFFFF"
android:ellipsize="marquee"
android:singleLine="true" />
make another xml named as spinner_dropdown and write below code
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
style="?android:attr/spinnerItemStyle"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:paddingLeft="4dp"
android:textSize="18sp"
android:textColor="#000000"
android:ellipsize="marquee"
android:singleLine="true" />
now update your code as below
ArrayAdapter<String> dAdapter = new ArrayAdapter<String>(this,
R.layout.spinner_layout,lb);
dAdapter.setDropDownViewResource(R.layout.spinner_dropdown);
My main layout main.xml has only a Button, a EditText and an empty ListView as below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<LinearLayout
android:id="#+id/input_area"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="#+id/input_field"
android:layout_height="40dip"
android:layout_width="fill_parent"
android:layout_weight="5"
/>
<Button
android:id="#+id/send_btn"
android:layout_width="60dip"
android:layout_height="30dip"
android:text="#string/send"
android:layout_weight="1"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/output_area"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#006633"
android:visibility="gone"
>
<ListView
android:id="#+id/output_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dip"
>
<!-- When "send" button in above input_area is pressed,
text from EditText field show here programmatically as a new row of the listview-->
</ListView>
</LinearLayout>
</LinearLayout>
As you see above, there are two child LinearLayout hosted by main LinearLayout.
The 1st child LinearLayout with id input_area consists of a EditText and a Button.
The 2nd child LinearLayout with id output_area is an LinearLayout with an empty ListView, AND its visibility is set to "gone".
The feature I am going to implement is very simple, that's in the input_area, when user input some text in the EditText field, and press the send button, then the input string should be shown in the output LinearLayout as a new row of the listview programmatically.
What I tried is the java code below:
EditText inputTxt = (EditText) findViewById(R.id.input_field);
Button sendBtn = (Button) findViewById(R.id.send_btn);
LinearLayout outputArea = findViewById(R.id.output_area);
//Updated by Saurabh
ListView lv = findViewById(R.id.output_list);
MyListAdapter mAdapter = new MyListAdapter(this, arraylist);
//Update finished
sendBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
int visibility = outputArea.getVisibility();
if(visibility==View.GONE)
// set ListView visible
outputArea.setVisibility(View.VISIBLE);
//get user input
String userInput = inputTxt.getText().toString(); // show this string in a new row of listview
//BUT how to dynamically add new row to the listview here???
}
});
But I am not sure how to add new row to the listview programmatically, anyone can help me?
By the way, I have another layout xml fiel (row.xml) which defined each row's layout.
-----------------------UPDATE------------------------------------
Each row of the list contain a icon and a text string. My list adapter and row layout are showing below:
My adapter:
private static class MyListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
ArrayList<String> arraylist;
public MyListAdapter(Context context, ArrayList<String> arraylist) {
mInflater = LayoutInflater.from(context);
this.arraylist = arraylist;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row, null);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
holder.userInput = (TextView) convertView.findViewById(R.id.user_input);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setImage(???);
holder.userInput.setText(arraylist.get(position));
return convertView;
}
static class ViewHolder {
ImageView icon;
TextView userInput;
}
}
my list row layout:
<?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="horizontal"
>
<ImageView
android: id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/user_input"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textSize="10dip"/>
</LinearLayout>
Make a Global variable as below
ArrayList<String> arraylist = new ArrayList<String>();
On Click of send button update the adapter that you are setting on ListView by adding
String userInput = inputTxt.getText().toString();
arraylist.add(userInput)
in adapter and then call
adapter.notifyDataSetChanged();
Update
I updated answer in your question and in this post copy your new Adapter class and use that