GridLayout adding customView as a child issue, Android - java

i have made a simple timetable with GridLayout and it looks like this
Now the idea is to insert required subject into specific row and column. In order to achieve that i have created a class that extends CardView in which i need to insert TextView.
code:
TimeTable.xml
<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="match_parent"
android:columnCount="8"
android:columnOrderPreserved="true"
android:rowCount="6"
tools:context="com.digiart.schoolapp.fragments.TimetableFragment">
<android.support.v7.widget.CardView
android:id="#+id/timetable_card_space"
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_columnWeight="1"
android:layout_row="0"
app:cardElevation="2dp"
app:contentPadding="5dp">
<TextView
android:id="#+id/timetable_dummy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="time"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:visibility="invisible" />
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/timetable_day1_card"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_row="0"
app:cardElevation="2dp"
app:contentPadding="5dp">
<TextView
android:id="#+id/timetable_day1_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Monday"
android:textAppearance="#style/TextAppearance.AppCompat.Body2" />
</android.support.v7.widget.CardView>
.....
........
<android.support.v7.widget.CardView
android:id="#+id/timetable_time1_card"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_row="1"
app:cardElevation="2dp"
app:contentPadding="5dp">
<TextView
android:id="#+id/timetable_time1_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="09.00"
android:textAppearance="#style/TextAppearance.AppCompat.Body2" />
</android.support.v7.widget.CardView>
.....
......
</GridLayout>
TimetableSubject:
public class TimetableSubject extends CardView {
TextView subjectText;
public TimetableSubject(Context context,int column,int row,int columnSpan,String subjectName) {
super(context);
GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams();
subjectParam.columnSpec = GridLayout.spec(column,columnSpan);
subjectParam.rowSpec = GridLayout.spec(row);
subjectText = new TextView(context);
CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
subjectText.setText(subjectName);
subjectText.setLayoutParams(textParams);
setLayoutParams(subjectParam);
}
}
Now i get what i need to do, i need to pass row and column to the custom view, and set those as layout params. the issue i think is with the Layout parameters code, i must be messing something up there. Could anyone explain how to set layout params for this situation properly? Thanks.

This is an age old ticket and I know this is marked as solved, but I'll just leave my experience here. I faced a somewhat similar issue: I was using custom views - extended RelativeLayout - inside GridLayout, I wanted to create a Grid with two columns and N rows (rows don't matter in my case). My custom views did not want to stretch horizontally, to take up the space they have. I have tried the support library, the Android X version of the library, weights, gravity - none of these worked.
It turns out that the GridLayout's parameters were set ok. My custom view was the problem. In my case there was no need to subclass a RelativeLayout, simply subclass a LinearLayout and you can still have whatever layout built inside.
Solution:
<androidx.gridlayout.widget.GridLayout
android:id="#+id/grid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/activity_margin"
android:layout_marginEnd="#dimen/activity_margin"
app:columnCount="2">
<custom.MenuButtonGrid
android:id="#+id/item1"
app:abg_title="Title1"
app:layout_columnWeight="1"
app:layout_gravity="fill" />
<custom.MenuButtonGrid
android:id="#+id/item2"
app:abg_title="Title2"
app:layout_columnWeight="1"
app:layout_gravity="fill" />
<custom.MenuButtonGrid
android:id="#+id/item3"
app:abg_title="Title3"
app:layout_columnWeight="1"
app:layout_gravity="fill" />
</androidx.gridlayout.widget.GridLayout>
The implementation of MenuButtonGrid:
/**
* A component that creates a card view with an icon and texts.
* They are designed to use as buttons.
*/
class MenuButtonGrid #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
private var binding =
LayoutButtonGridViewBinding.inflate(LayoutInflater.from(context), this, true)
init {
// do whaterver you want in here
}
}
The inside of layout_button_grid_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp">
// Content doesn't matter here
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

You should go with TableLayout. In TableLayout you can create any number of rows and column. Go through the TableLayout documentation and read the concepts of rows and column. Here is a very nice tutorial for table layout.
This tutorial is also very helpful for you.

There was an issue with GridLayout weight parameter in Spec. Managed to solve the problem by inserting weight as a float parameter in Spec
Code:
public class TimetableSubjectView extends CardView {
TextView subjectText;
public TimetableSubjectView(Context context, int column, int row, float columnWeight, String subjectName, int color) {
super(context);
GridLayout.Spec rowI = GridLayout.spec(row,1,columnWeight);
GridLayout.Spec colI = GridLayout.spec(column,1,columnWeight);
GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams(rowI,colI);
subjectParam.setMargins(5,5,5,5);
setBackgroundColor(color);
subjectText = new TextView(context);
CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
subjectText.setText(subjectName);
subjectText.setGravity(Gravity.CENTER);
subjectText.setLayoutParams(textParams);
this.addView(subjectText);
setLayoutParams(subjectParam);
}
}

Related

Dynamically Created Layout not Showing

I've looked at this question here, however I still cannot find out what I'm doing wrong. There are no errors in Logcat and there definitely is data being passed to it to be made. Here's my setup:
This is all taking place below manually placed elements that I have placed in Android Studio. I have a ScrollView. Inside that ScrollView, I have a LinearLayout, parentLayout, that get's passed to this class. This method is supposed to add another Horizontal LinearLayout, layout, parentLayout. Then it is supposed to add a TextView, titleDisplay, and two Buttons to layout. So far I have only programmed just layout and titleDisplay. I tested it, and nothing was added. So before I program the other two buttons, I would like to know what I am doing wrong. Here's the Java Code:
public class FollowupOption {
private String displayName;
private JSONObject jsonInformation;
private Context context;
private LinearLayout parentLayout;
private LinearLayout layout;
private TextView titleDisplay;
private Button deleteButton, editButton;
public FollowupOption(String displayName, JSONObject jsonInformation,
Context context, LinearLayout parentLayout){
this.displayName = displayName;
this.jsonInformation = jsonInformation;
this.context = context;
this.parentLayout = parentLayout;
buildLayout();
}
private void buildLayout(){
//Horizontal Linear Layout to hold everything
this.layout = new LinearLayout(context);
this.layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
this.layout.setOrientation(LinearLayout.HORIZONTAL);
this.parentLayout.addView(this.layout);
//Text View Displaying title of followup option.
this.titleDisplay = new TextView(context);
try {
this.titleDisplay.setText(this.jsonInformation.getJSONObject("list").getString("title"));
} catch(JSONException e){ e.printStackTrace(); }
this.titleDisplay.setTextColor(0x8f142a); //Black
this.titleDisplay.setTextSize(18);
this.titleDisplay.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
this.layout.addView(this.titleDisplay);
}
}
Here's my XML:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="38dp"
android:orientation="horizontal">
<TextView
android:id="#+id/textView15"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.22"
android:gravity="center"
android:text="#string/followup_text"
android:textColor="#color/myRed"
android:textSize="18sp" />
<Button
android:id="#+id/followup_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="#string/plus"
android:textAlignment="center"
android:textColor="#android:color/holo_green_dark"
android:textSize="30sp"
android:textStyle="bold" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="279dp"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:paddingTop="7dp">
<LinearLayout
android:id="#+id/followup_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/followup_new_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/new_followup_text" />
</LinearLayout>
</merge>
If someone could let me know what I am doing wrong or a good way to debug something like this, that would be appreciated.
Are you adding this.layout view to some view?
UPD: The problem is with your text color. Consider using the Color class to get color from its hex value or constants from that class.
Does your XML view (without the addition of the dynamic layout) take up the entire screen?
The new LinearLayout view will be added below the button. If the button is at the bottom of the screen, the layout will be added off the screen and therefore not visible.
You should add your new layout to the scroll view instead.

Adding Views with Java LayoutInflater in a loop either doesn't set the width or only adds the first item in the loop

I have function that loads data form a server, like a search then adds these tot the main menu.
To accomplish this I am using a for loop on the JSON results to add the items.
This loop works fine, it reads the data and loops through fine:
Java Loop:
JSONArray teams = result.getJSONArray("teams");
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout parent = (LinearLayout) mainMenu.findViewById(R.id.team_list_view);
//Log.d("TEAMS",teams.toString());
for(int x = 0; x < teams.length(); x++) {
JSONObject cTeam = teams.getJSONObject(x);
String name = cTeam.getString("name");
String thumb = cTeam.getString("thumb");
String id = cTeam.getString("id");
View custom = inflater.inflate(R.layout.teams_menu_template, null);
int width = LinearLayout.LayoutParams.FILL_PARENT;
int height = LinearLayout.LayoutParams.WRAP_CONTENT;
ImageButton pp = (ImageButton) custom.findViewById(R.id.tempPPbtn);
Button teamName = (Button) custom.findViewById(R.id.tempPPTxtbtn);
teamName.setText(name);
loadImage loadImage = new loadImage("imagebutton",pp);
loadImage.execute(thumb);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,height);
parent.addView(custom);
}
Now this does work fine it loops through and adds the image and text and appends to the parent layout. But instead of stacking the new layouts it places them side by side like in the image below:
After some googling I tried adding params to set the width to FILL_PARENT but the outcome only adds the first item. However it does add it as I want.
I've stuck on this for quite some time, if anyone can help it would be greatly appriated.
My Template XML file i'm using.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:id="#+id/tempDropCont"
android:background="#drawable/drop_down"
android:weightSum="100"
android:baselineAligned="true">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="2">
<LinearLayout
android:orientation="vertical"
android:layout_width="70dp"
android:layout_height="wrap_content">
<ImageButton
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/tempPPbtn"
android:background="#drawable/profile"
android:layout_marginLeft="15dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="20dp">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/leader_board"
android:id="#+id/tempPPTxtbtn"
android:background="#android:color/transparent"
android:textColor="#color/white"
android:textSize="20sp"
android:layout_marginTop="10dp" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tempDrop"
android:visibility="gone">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/view_team"
android:id="#+id/tempTxtBtn1"
android:background="#android:color/transparent"
android:textColor="#color/white"
android:textSize="20sp"
android:layout_marginTop="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/edit_team"
android:id="#+id/tempTxtBtn2"
android:background="#android:color/transparent"
android:textColor="#color/white"
android:textSize="20sp"
android:layout_marginTop="10dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/team_settings"
android:id="#+id/tempTxtBtn3"
android:background="#android:color/transparent"
android:textColor="#color/white"
android:textSize="20sp"
android:layout_marginTop="10dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
At first I did think it was the xml but I have tried using include on a different layout and it includes the file fine as its supposed too.
NOTE from the server there is two items returned.
It would have been nice to have the parent layout as well, or at least the way you defined the parent (LinearLayout with the id listview).
However, there are several culprits for the behavior that you describe:
Make sure that the parent layout has the orientation set to vertical. At this point you can copy paste a couple of template items in your layout and see if they look alright when you define them in xml
When you inflate your item, you need to pass the parent as well, so that the child inherits the layout properties:
View custom = inflater.inflate(R.layout.teams_menu_template, parent, false);
This will create the item with the expected properties as defined in the parent container, but not attach it to the parent just yet.
This line is not used:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,height);
You don't set the parameters once you created them. But I think this will be redundant once you do the inflation properly.

Custom Views, to insert them dynamically to Layout in Java

I can't stress that often enough, I am new to Android and Java in general :-)
And these xml layouts are giving me headaches.
The code what you see consist of two ImageViews and two TextViews inside a RelativeLayout, together they form a layout which for me works as a "custom button". When I copy and paste it inside my layout it works almost the way I want.
How can I use this part of xml-layout dynamically in my code whenever I need a button like that and still be able to change certain properties, like the text inside the textviews?
I hope you understand what I mean, my first language is not english.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:src="#drawable/box" />
<TextView
android:id="#+id/myImageViewText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/myImageView"
android:layout_alignLeft="#+id/myImageView"
android:layout_alignRight="#+id/myImageView"
android:layout_alignTop="#+id/myImageView"
android:layout_margin="1dp"
android:gravity="center"
android:text="S-"
android:textColor="#000000"
android:textStyle="bold" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/myImageViewText"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:text="your turn!"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView1"
android:layout_alignParentTop="true"
android:layout_marginBottom="15dp"
android:layout_marginTop="-10dp"
android:cropToPadding="false"
android:src="#drawable/icon" />
</RelativeLayout>
Ok to start extend your own view like this one:
I do have a Button made with an ImageView and a TextView in a LinearLayout designed in xml:
XML
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/ivImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:adjustViewBounds="true"
android:padding="3dp"
android:scaleType="fitStart" />
<TextView
android:id="#+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_marginLeft="10dp"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#android:color/white" />
</merge>
ViewObject called
ViewMenuButton
public class ViewMenuButton extends View{
private TextView tvText;
private ImageView ivImage;
public ViewMenuButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ViewMenuButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ViewMenuButton(Context context) {
super(context);
init();
}
private void init() {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//here you can inflate a own XML for that View
inflater.inflate(R.layout.view_menubutton, this, true);
this.tvText= (TextView)this.findViewById(R.id.tvText);
this.ivImage = (ImageView)this.findViewById(R.id.ivImage);
}
public void setText(String text){
if(this.tvText != null){
tvText.setText(text);
}
}
//... and so on
}
Whenever you want to use it in your xml make sure to give the View the complete package like this:
Usage XML
<com.your.package.views.ViewMenuButton
android:id="#+id/menu_bt_local"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:background="#drawable/action_button"
android:textSize="#dimen/text_cell" >
If you want to use it in a code just make it like this:
Usage JAVA
LinearLayout rootView =
(LinearLayout) findViewById(R.id.mainLayout); //Or sth like this
ViewMenuButton vmb = new ViewMenuButton(this);
rootView.add(vmb);
//or if you already have it in XML
ViewMenuButton vmb = (ViewMenuButton) findViewById(R.id.myVmbtID);
You can even go more in detail defining your own attributes to use in XML, like setting source of the Image, changing Text, changing TextColor etc pp Tutoiral
Create your custom View subclass. Inflate your layout in it's constructor, find necessary views there and create setters/getters of necessary properties. Then each time you need this custom button you'll be able to create it through code or xml using this subclass. If you need to be able to change some properties from xml too you may want to declare styleable attributes for your custom view. I think you can find lots of tutorials about how to create custom views.
Here's the common tutorial. Here you can read about custom attributes. And finally here is the best example of what I mentioned above.
You can inflate your layout and add it to another layout
RelativeLayout layout = new RelativeLayout(this);
View childButton = getLayoutInflater().inflate(R.layout.child_button, null);
layout.addView(childButton);
Now you can find the child views in the button layout as
TextView textViewInnerChild = (TextView)childButton.findViewById(R.Id. textInnerView):
Then you can change the value or properties of the inner child views
textViewInnerChild.set text("your text")

Dynamic list of checkboxes with onclick functions

I have a page that returns a list of items backs from a database. I want to add each item to my android fragment as a checkbox dynamically with an onClick, that can tell if an item is being checked or un-checked.
How can I add checkboxes dynamically with on-clicks and different titles for each?
Below is the xml I am inserting the checkboxes into:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#e5e5e5"
android:layout_height="match_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:orientation="vertical"
android:background="#drawable/bg_card">
<!-- Card Contents go here -->
<TextView
android:id="#+id/styleDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:textSize="15sp"
android:padding="5dip"
></TextView>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New CheckBox"
android:id="#+id/checkBox" />
</LinearLayout >
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:orientation="horizontal"
android:background="#drawable/bg_card">
<!-- Card Contents go here -->
<Button
android:id="#+id/buttonAddList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create List"
style="?android:attr/borderlessButtonStyle"
android:textColor="#color/orange"
android:textStyle="bold"
/>
</LinearLayout >
</FrameLayout>
</LinearLayout>
</ScrollView>
I currently have one checkbox in the above code. I plan on removing this. That checkbox is just to show where I want my check boxes to show up.
What you need to do first is add an id to your LinearLayout (in that XML file), the one which is going to hold the CheckBoxes. Then, in the code you need to get that LinearLayout by its id and use addView() to add CheckBoxes that you create dynamically. I imagine in pseudocode it'd look like this:
for (int i = 0; i < numberOfCheckBoxes; i++) {
CheckBox checkBox = new CheckBox();
checkBox.setTitle("Your title");
checkBox.setOnClickListener(new OnClickListener() {
// Your code to be executed on click
});
linearLayout.addView(checkBox);
}
Does this help?
PS: It'd be nice if you kept your code clean - ADT (and I believe Eclipse too) gives you the Shift+Ctrl+F shortcut to indent your code automatically - use it as often as possible ;)
Since you are processing database items, I suggest using a CursorAdapter to do the heavy work for you. A CursorAdapter, like any of the Adapter classes can process the database items and custom-fit them into a layout of your choice, to use in a ListView.
You have to make adjustments to your code:
Create a layout file that contains whatever you want to put in the dynamic list. This is an example, say it's named list_contents.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:orientation="vertical"
android:background="#drawable/bg_card">
<!-- Card Contents go here -->
<TextView
android:id="#+id/styleDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:textSize="15sp"
android:padding="5dip"
></TextView>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New CheckBox"
android:id="#+id/checkBox" />
</LinearLayout >
</FrameLayout>
Then, instead of returning a List from your AsyncTask, return the Cursor itself
from your database. This Cursor will be processed by CursorAdapter. I recommend this guide:
http://www.gustekdev.com/2013/05/custom-cursoradapter-and-why-not-use.html
Implement the CursorAdapter methods:
In your implementation of newView(), inflate list_contents.xml (Note that if you use ResourceCursorAdapter you wouldn't need to do this)
In your implementation of CursorAdapter.bindView() do this:
CheckBox checkbox = (CheckBox) view.findViewById(R.id.checkbox);
checkbox.setText(cursor.getString(cursor.getColumnIndex(YOUR_DATABASE_COLUMN_NAME_FOR_CHECKBOX_VALUES)));
checkbox.setOnCheckedChangedListener(listenerInitializedSomewhereFromFragmentCode);
Change your ScrollView to a ListView (it can be inside any Layout), and give it an id, say R.id.listview.
Finally, in the part where you process the List from the database, where we now have a Cursor instead, just do this:
CustomCursorAdapter cca = new CustomCursorAdapter(getActivity(), resultFromDatabase, 0);
listView.setAdapter(cca);
Note: getActivity() is for when you are working inside a Fragment. It should be a context, so inside an Activity it can just be "this".
Note2: listView should have been initialized at this point via findViewById.
Note3: If listView already has an Adapter and Cursor set, you should consider calling listView.getAdapter().changeCursor() instead.
Simple Code In Kotlin
fun createCheckbox() {
var arr_cb = arrayOfNulls<CheckBox>(checkbox_size)
val layout = findViewById<View>(R.id.layout_checkbox) as ViewGroup
val ll = LinearLayout(this)
ll.orientation = LinearLayout.VERTICAL
for (i in 0 until arr_cb.size) {
arr_cb[i] = CheckBox(this)
arr_cb[i]?.text = health_status.get(i).toString()
arr_cb[i]?.setPadding(25, 0, 0, 0)
arr_cb[i]?.id = i
arr_cb[i]?.tag = health_status[i]
arr_cb[i]?.setTextColor(resources.getColor(R.color.title_color))
arr_cb[i]?.setOnCheckedChangeListener(
arr_cb[i]?.let {
handleCheck(it)
})
arr_cb[i]?.buttonTintList =
ColorStateList.valueOf(resources.getColor(R.color.theme_color))
ll.addView(arr_cb[i])
}
layout.addView(ll)
}
handleCheck method
private fun handleCheck(chk: CheckBox): CompoundButton.OnCheckedChangeListener? {
return object : CompoundButton.OnCheckedChangeListener {
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
if (!isChecked) {
//uncheck
} else {
//check
}
}
}
}
and you want to do something use direct checkboxList object like as
val layout = findViewById<View>(R.id.layout_checkbox) as ViewGroup
val ll = LinearLayout(this#MedicalHistoryActivity)
ll.orientation = LinearLayout.VERTICAL
for (i in 0 until health_status.size) {
arr_cb[i]?.isEnabled = true
// do something like change color or more
}
layout.addView(ll)
for enable checkbox or more.
Thank you

Gridview alignment of elements

I have a grid view with 7 images, and now when I inflate it I get it like this
Here you can see the images are aligned as per normal view
But I dont want it like that I want it like this
The bottom images are aligned to form kind of a pyramid or triangle type
How can i achieve this in gridview in android ???
If you try to set the padding then you get the view to be shrinked like this
if(position == 4){
view.setPadding(50, 0, 0, 0);
}
So I would suggest something like this
Create 2 gridviews in xml as this such that they have their alignments centered
<TextView
android:id="#+id/txtControl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<GridView
android:id="#+id/gridView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/txtControl"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:numColumns="4" >
</GridView>
<GridView
android:id="#+id/gridView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtControl"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:numColumns="3" >
</GridView>
Now In your main activity create 2 String values for each
public class MainActivityWrapped extends Activity {
static final String[] MOBILE_OS1 = new String[] {
"Android", "iOS", "Windows", "Blackberry"};
static final String[] MOBILE_OS2 = new String[] {
"Android", "iOS", "Windows"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridviewlayout);
GridView gridView1 = (GridView) findViewById(R.id.gridView1);
gridView1.setAdapter(new ImageAdapterWrapped(this, MOBILE_OS1,gridView1));
GridView gridView2 = (GridView) findViewById(R.id.gridView2);
gridView2.setAdapter(new ImageAdapterWrapped(this, MOBILE_OS2,gridView1));
}
}
Either you can create 2 adapter or control the same 1st adapter to be reused
The output would be like this
As Takendarkk comments, the layout you want is not a grid
You should be able to achieve what you want with nested linearlayouts:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- first 4 image views here -->
</LinearLayout>
<LinearLayout
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- last 3 image views here -->
</LinearLayout>
</LinearLayout>
This is do-able, but the solution is messy.
If you know how many images are going to be in the row, you can calculate how much padding you'll need on the left and right images of your row.
Then, in your getView() of your adapter, you can set this padding bearing in mind that due to the way views are recycled in adapters, you'll need to unset the padding for those that do not need it.
Let me know in a comment if you need some code to better illustrate what I'm proposing.

Categories