Programatically add LinearLayout with Text and Image - java

I'm trying to add a LinearLayout for each item in a varying Array. I need each item to have an image and text horizontally, but for now I am testing with the text.
Keeping in mind this code is in a Fragment.
I think the error is with the getContext() but not to sure.
The code I currently have is:
List<PaymentOption> paymentOptions = aTradeItem.getPaymentOptions();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(ImageUtils.dpToPx(16), ImageUtils.dpToPx(4), ImageUtils.dpToPx(16), ImageUtils.dpToPx(4));
LinearLayout.LayoutParams lineparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ImageUtils.dpToPx(1));
lineparams.setMargins(0, ImageUtils.dpToPx(4), 0, ImageUtils.dpToPx(4));
if (paymentOptions != null && paymentOptions.size() > 0) {
for (PaymentOption t : paymentOptions) {
LinearLayout paymentOptionLayout = new LinearLayout(getContext());
paymentOptionLayout.setOrientation(LinearLayout.HORIZONTAL);
paymentOptionLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
TextView heading = new TextView(getContext());
heading.setText(t.getDescription());
heading.setTextColor(getResources().getColor(R.color.light_text));
heading.setLayoutParams(lp);
paymentOptionLayout.addView(heading);
}
}
There are no errors, the data just doesnt populate on the screen. I have tried Hardcoding random text in the setText() but with no success.
Thank you

You're not adding your paymentOptionLayout to the layout which is set as your content View. Basically what you're doing is programatically creating the layout, but then doing nothing with it.
By default your activity_main.xml file will come with some type of layout depending on how you setup your code, for example a blank activity's xml file would be
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
android:id="#+id/RelativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
However when you create layouts programmatically the way you did, you must append them to the layout which is the parent layout in your XML file.
So I think what you need to do is the following.
RelativeLayout rl=(RelativeLayout)findViewById(R.id.RelativeLayout); //getting the view from the xml file. Keep in mind that the id is defiend in the xml file by you
List<PaymentOption> paymentOptions = aTradeItem.getPaymentOptions();
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(ImageUtils.dpToPx(16), ImageUtils.dpToPx(4), ImageUtils.dpToPx(16), ImageUtils.dpToPx(4));
LinearLayout.LayoutParams lineparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ImageUtils.dpToPx(1));
lineparams.setMargins(0, ImageUtils.dpToPx(4), 0, ImageUtils.dpToPx(4));
if (paymentOptions != null && paymentOptions.size() > 0) {
for (PaymentOption t : paymentOptions) {
LinearLayout paymentOptionLayout = new LinearLayout(getContext());
paymentOptionLayout.setOrientation(LinearLayout.HORIZONTAL);
paymentOptionLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
TextView heading = new TextView(getContext());
heading.setText(t.getDescription());
heading.setTextColor(getResources().getColor(R.color.light_text));
heading.setLayoutParams(lp);
paymentOptionLayout.addView(heading);
rl.addView(paymentOptionLayout); //adding the view to the parent view
}
}
Please note that from the looks of your code, you're really just reimplementing listView which is an available layout in android. I think you should take a look at that.

getContext() is a method of activity class. It returns the context view only for currently running activity.
For Fragment either pass the instance of current activity class via constructor or use getActivity() method or this instead of getContext()
See here for help
Using context in a fragment
How to add view into LinearLayout of Fragment by onClick?
Also add paymentOptionLayout to the parent layout view right after for loop.

Related

findViewById of a Constraint Layout returns null

I have a problem with findViewById using Java in Android Studio. I'm triying to obtain a Constraint Layout to use .addview in it but it returns null.
This is the layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="#+id/gameLayout"
tools:context=".GameActivity">
This is the line with problems:
ConstraintLayout mainLayout = (ConstraintLayout) findViewById(R.id.gameLayout);
And it returns null, what am I doing bad?
Thanks
Edit: Now I'm getting stucked afther this loops, what can be?
protected void generateGameZone(int m, int n){
LinearLayout[] main_layouts = new LinearLayout[m];
for(int i=0;i<main_layouts.length;i++){
main_layouts[i] = new LinearLayout(this);
main_layouts[i].setOrientation(LinearLayout.HORIZONTAL);
main_layouts[i].setLayoutParams(new LinearLayout.LayoutParams(30,30));
mainLayout.addView(main_layouts[i]);
}
LinearLayout[][] secondary_layouts = new LinearLayout[m][n];
for(int i=0;i<secondary_layouts.length;i++){
for(int j=0;j<secondary_layouts[i].length;j++){
secondary_layouts[i][j] = new LinearLayout(this);
secondary_layouts[i][j].setOrientation(LinearLayout.HORIZONTAL);
secondary_layouts[i][j].setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));
TextView txtBox = new TextView(this);
txtBox.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
txtBox.setId(i*10 + j);
secondary_layouts[i][j].addView(txtBox);
main_layouts[i].addView(secondary_layouts[i][j]);
}
}
}
I obtain a black screen
Edit2: Black screen solved, now the layout I create with loops its not being showed
From your question it seems like you are trying to add the ConstraintLayout programmatically to your activity. However findViewById(int) called from an Activity tries to find the already existing view in the hierarchy and returns null if it isn't found.
I think what you are looking for is either to inflate the layout using a LayoutInflater and then add it using addView as you suggested, or if this layout represents the root of your activity, use setContentView(int) to let the activity handle the inflation.

How add array of TextViews into Relative layout without overlapping programmatically in android?

I'm looking for a solution to solve my problem which all my TextViews overlaps on themselves, when are added to Relative Layout. In fact, I need to do put them after each. other I've read existed answers, I followed them but nothing could solve it yet. can someone tell me where I did wrongly?
here is my code:
for (int i=0;i<parts.length;i++)
{
valueTV[i] = new TextView(this);
valueTV[i].setText(parts[i]);
valueTV[i].setId(i);
valueTV[i].setWidth(300);
RelativeLayout.LayoutParams lparams = new RelativeLayout.LayoutParams
(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
linearLayout_Skills.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
linearLayout_Skills.setBackgroundColor(getResources().getColor(R.color.blue));
if(i>=1)
{
lparams.addRule(RelativeLayout.END_OF, valueTV[i-1].getId());
valueTV[i].setLayoutParams(lparams);
}else {
lparams.addRule(RelativeLayout.ALIGN_PARENT_START);
valueTV[i].setLayoutParams(lparams);
}
linearLayout_Skills.addView(valueTV[i]);
}
XML code:
<RelativeLayout
android:id="#+id/linearSkills"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="rtl"
android:paddingTop="5dp"
</RelativeLayout>
You can achieve this using Relative layout
So this is the main idea , first you define your relation layout
//layout variable is your relative layout
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(layoutParams);
Then you define a param variable like this
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
After that you define your textView with an id (in your case this id can be its position in the array)
TextView tv1 = new TextView(this);
tv1.setId(1);
tv1.setText("textView1");
The next textView will be declared like this
TextView tv2 = new TextView(this);
params1.addRule(RelativeLayout.BELOW, tv1.getId());
tv2.setId(2);
tv2.setText("textView2");
Finally you set your view using the params you defined
layout.addView(tv2, params1);
Here is a complete example you can check answer by #AndiM

App crashes when setting background colour

Every time I run my app it crashes giving me a nullpointerexception, I want to programatically change my background depending on the scenario, here is my code:
Main Activity:
public class Activity extends AppCompatActivity {
ConstraintLayout layout;
String messageSafe = "Item is Safe for Consumption";
String messageUnSafe = "Item is NOT Safe for Consumption";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
layout = new ConstraintLayout(this);
if (matched.length == 0) {
layout.setBackgroundResource(R.drawable.background_safe);
setContentView(layout);
changeColor("#00FF00");
messageView.setText(messageSafe);
}
else{
layout.setBackgroundResource(R.drawable.background_unsafe);
setContentView(layout);
changeColor("#FF0000");
messageView.setText(messageUnSafe);
}
ListView listContains = (ListView) findViewById(R.id.lvItemsFound);
ArrayAdapter<String> contains = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, foundItems);
listContains.setAdapter(contains);
ListView listRestricted = (ListView) findViewById(R.id.lvItemsRestricted);
ArrayAdapter<String> found = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, matched);
listRestricted.setAdapter(found);
}
You are losing reference to your old view because you changed the layout to a new ConstraintLayout object. This means you now don't have your ListView objects and other items in your XML because that View is gone. It's not the ContentView anymore. If you want to work on the existing layout, you need to give the root view an ID.
<constraintlayout android:id="#+id/container" ... />
Then you can reference that ID with findViewById(R.id.container) and use the object you get from it to change your background like you are doing.
Try this:
1. Give your root view an ID
2. Set a ConstraintLayout object with ConstraintLayout layout = findViewById(R.id.container) (Note: You can call it anything, not just container, I am just going off my example from above, since I gave it the ID 'container')
3. call setBackgroundResource() like you are doing.
4. No need to call setContentView() again, this was set in the beginning, and you do not want to reset it to a new view you just constructed like you were initially doing.
5. You shouldn't crash when trying to call setAdapter() to your ListView now because you don't have a reference to an object that isn't in your content view.
layout = (ConstraintLayout)findViewById(R.id.container);
if (matched.length == 0) {
layout.setBackgroundResource(R.drawable.background_safe);
changeColor("#00FF00"); //assuming this is some local function?
messageView.setText(messageSafe);
}
else{
layout.setBackgroundResource(R.drawable.background_unsafe);
changeColor("#FF0000");
messageView.setText(messageUnSafe);
}
You are trying to set the background by replacing the view of your activity (this is what setContentView() does). This causes a null pointer exception later because the old layout (defined in the XML) has been replaced, so your list view no longer exists.
Instead, you should get a reference to the existing root view (the ConstraintLayout, although if you're just setting background you can just reference it as a View, no need to be so specific), and set the background on it, like so:
findViewById(R.id.container).setBackgroundResource(R.drawable.unsafe);
You'll also need to give the containing layout an id in the existing layout XML:
<android.support.constraint.ConstraintLayout
android:id="#+id/container"
... etc.

Show activity in Frame Layout

I have one layout called sample.xml
`
<FrameLayout
android:id="#+id/actionbar"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
`
i have two class
one is tab.java
second is wallpaper.java
so can any one suggest me how can i show wallpaper.java in frame-layout
Using Fragment is the best option to achieve what you want.
But if you don't want to do it, you can make your welcome.java a normal file(not an activity) and return your layout as a view from that file.
Then you can directly add this returned view into your FrameLayout.
EDIT
1) Remove the extends Activity from your class.
2) Remove all #Override from that class.
3) Change your onCreate to this:-
Activity activity;
View v;
public View onCreate(Activity activity)//change the name if you want
{
this.activity = activity;
Typeface rt=Typeface.createFromAsset(getAssets(),"font/Carleton.ttf");
//super.onCreate(savedInstanceState);
//setContentView(R.layout.wallpaper);
LayoutInflator li = activity.getLauoutInflator();
v = li.inflate(R.layout.wallpaper, null);
.
.
.
return v;
}
4) Replace all findViewById with v.findViewById
5) Replace all getResources() with activity.getResources()
6) Then in your tab.java add the onCreate of welcome.java in your FrameLayout as
Welcome welcome = new Welcome();
frameLayout.addView(welcome.onCreate(this));
I am not getting what you want to achieve..
But If you want to use layout something like tabs, you can achieve it using ViewPager or TabHost
EDIT
This might help you to achieve your requirement.

android - TextView getting scrollbar to always show programatically

I am dynamiclly creating a View which contains an image and a TextView this is then being added to a ViewFlipper. This is all working as it should the issue is I require the scrollbar to always be visible, however I simple cannot get it to work and am not sure what I am doing wrong.
Below is my dynamic code and the xml code which I am trying to replicate
for(int i = 0; i < 5; i++)
{
// Creating my linear layouts & views
lls = new LinearLayout(this);
llv = new LinearLayout(this);
lls.setOrientation(LinearLayout.VERTICAL);
// Adding image view
imgStory = new ImageView(this);
imgStory.setImageResource(GetImage(i));
imgStory.setLayoutParams(new LayoutParams(width, width));
lls.addView(imgStory);
// adding textview, which is scrollable
txtStory = new TextView(this);
txtStory.setText(unescape(story.get(i)));
txtStory.setTextColor(getResources().getColor(R.color.orange));
txtStory.setPadding((int)padding, (int)padding, (int)padding, (int)padding);
txtStory.setMovementMethod(new ScrollingMovementMethod());
//txtStory.setVerticalScrollBarEnabled(true);
//txtStory.setVerticalFadingEdgeEnabled(false);
lls.addView(txtStory);
// Adding views to my view flipper
llv.addView(lls);
viewFlipper.addView(llv, i);
}
XML code I am trying to replicate programatically
<TextView
android:id="#+id/txtStoryText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/imgStoryLine"
android:layout_above="#+id/footer"
android:layout_margin="20dp"
android:scrollbars="vertical"
android:scrollbarSize="10dp"
android:fadeScrollbars="false"
android:textColor="#color/orange"
android:text="" />
How about trying to use a ScrollView as the top most parent. So, something like this:
// Creating my linear layouts & views
lls = new LinearLayout(this);
llv = new ScrollView(this); // This looks like the view you're adding to the viewFlipper
lls.setOrientation(LinearLayout.VERTICAL);
Or, if it's just the text you want to scroll, make the first LinearLayout a Scrollview:
// Creating my linear layouts & views
lls = new ScrollView(this); // This wraps your textView
llv = new LinearLayout(this);
lls.setOrientation(LinearLayout.VERTICAL);
NOTE: this is not tested. Just trying to give you an idea. You may have to specify more layout parameters for the ScrollView to get this to work.
You can also take a look at this post where they talk about setting:
textView.setMovementMethod(new ScrollingMovementMethod())

Categories