TextView moved down when new line - java

I'm currently working on a server-client android application, and in one of my views I have a HorizontalScrollView that contains a vertical LinearLayout. This LinearLayout will contain a bunch of TextViews that are customized with a background. It works fine until the TextViews get a new row because of the character length, it looks like this:
http://puu.sh/9L127/bf29a86639.jpg
The idea is that the text is supposed to fit in the background, is there any way that I can keep the TextView position like the other ones, even though it has multiple rows?
I hope I made myself clear enough, this is how the TextViews are set up in the code:
public void setupCard(GameCard card) {
final int CARD_WIDTH = 200;
final int CARD_HEIGHT = 100;
m_card = card;
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(CARD_WIDTH, CARD_HEIGHT);
lp.setMargins(0, 0, 5, 0);
super.setText(m_card.getContent());
super.setBackgroundResource(R.drawable.cardbg);
super.setLayoutParams(lp);
super.setGravity(Gravity.CENTER);
}
And this is how the activity is set up:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#drawable/bng"
android:orientation="vertical" >
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/cardLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
Thanks in advance!

Thats because the LinearLayout alignes the text baselines of the TextViews.
Try to specify
android:baselineAligned="false"
for the LinearLayout.

Related

View.Gone inside adapter leaves space in onBindViewHolder

This is my onBindViewHolder method:
#Override
public void onBindViewHolder(#NonNull final mViewHolder h, int i) {
final JSON data = jdata[i];
if(data .getName() != null && data .getStatus() !=null) {
h.textcontainer.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
/*width*/ ViewGroup.LayoutParams.MATCH_PARENT,
/*height*/ ViewGroup.LayoutParams.WRAP_CONTENT,
/*weight*/ 1.0f
);
h.textcontainer.setLayoutParams(params);
h.title.setText(feed.getName());
} else {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
/*width*/ ViewGroup.LayoutParams.MATCH_PARENT,
/*height*/ ViewGroup.LayoutParams.WRAP_CONTENT,
/*weight*/ 2
);
h.textcontainer.setVisibility(View.GONE);
h.playerView.setLayoutParams(params);
}
and this my XML:
<LinearLayout
android:id="#+id/videopost_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_parent_rounded_corner"
android:orientation="vertical"
android:weightSum="2"
>
<LinearLayout
android:id="#+id/video_textcontainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingLeft="#dimen/feed_item_padding_left_right"
android:paddingRight="#dimen/feed_item_padding_left_right"
android:paddingBottom="#dimen/feed_item_padding_top_bottom"
android:paddingTop="#dimen/feed_item_padding_top_bottom"
android:layout_weight="1"
>
<TextView
android:id="#+id/video_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold"
android:textColor="#color/background"
android:paddingStart="#dimen/feed_item_profile_info_padd"
android:paddingEnd="#dimen/feed_item_profile_info_padd"
/>
</LinearLayout>
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/exo_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:show_buffering="true"
android:layout_weight="1"
>
</com.google.android.exoplayer2.ui.PlayerView>
My Adapter has a textview in it, when the json data = null, I obviously want to hide that TextView without any spacing left, and when the data (title for the video) isn't null, I want to show the text.
The current codes hides the TextView, but leaves an empty space. If I delete the following two lines from the if-statemant:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
/*width*/ ViewGroup.LayoutParams.MATCH_PARENT,
/*height*/ ViewGroup.LayoutParams.WRAP_CONTENT,
/*weight*/ 1.0f
);
h.textcontainer.setLayoutParams(params);
Then there's no empty space left, but the TextView won't display if the data isn't empty. I'm pretty sure this is some stupid error somewhere, but I'm not able to find it. SOS :-)
Firstly, you have two individual layouts LinearLayout and PlayerView sharing a weight sum of two (2) making it a 50:50 distribution. Whether the child view of the LinearLayout is gone the 50% space would still remain until it's given out.
Hence any time you need to hide textview/title completely and remove not-needed space, dynamically set the weight of PlayerView to two (2) and make the visibility of LinearLayout gone.
The LinearLayout around your TextView is redundant. You can simplify this to simply be a single LinearLayout with two children. Set the height to wrap_content and do not specify a weightSum. When the TextView's visibility is set to GONE, PlayerView will be the only visible child and your LinearLayout will match its size.
<LinearLayout
android:id="#+id/videopost_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg_parent_rounded_corner"
android:orientation="vertical">
<TextView
android:id="#+id/video_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/feed_item_profile_name"
android:textStyle="bold"
android:textColor="#color/background"
android:paddingStart="#dimen/feed_item_profile_info_padd"
android:paddingEnd="#dimen/feed_item_profile_info_padd"
/>
<com.google.android.exoplayer2.ui.PlayerView
android:id="#+id/exo_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:show_buffering="true"/>
</LinearLayout>

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.

Scroll on duplicated Layout - Android

Here I am using this code to paste my main_activity.xml on top of itself 5 times, making a long list of itself
Here is my code:
for(int i = 0; i < 5; i++){
LayoutInflater loiViewInflater = (LayoutInflater)
getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View mView = loiViewInflater.inflate(R.layout.activity_main,
null);
FrameLayout.LayoutParams params = new
FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0,i * 400,0,0);
addContentView(mView, params);
}
Everything works handy dandy, but how can I make it to where I can scroll down?
The activities go off the screen and I can't think of a way to scroll down. Is it possible?
Thanks, Cooper
You can always use a ScrollView, just set some container, like a linear layout, and copy your layout inside.
The hierarchy should look like:
ScrollView
LinearLayout
YourCopy
YourCopy
YourCopy
For instance, for your container view:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/list_container"
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
</LinearLayout>
</ScrollView>
And on your loop (once you set your layout above with setContentView) something like:
LinearLayout container = (LinearLayout)findById(R.id.list_container)
for(int i = 0; i < 5; i++){
// inflate and set up your layout mView
// (...)
container.addView(mView);
}
Basically, you are injecting your copies inside the LinearLayout (which is inside the ScrollView).
As Logain suggested, you can use a ScrollView and copy your layouts inside.Here is a sample.
<ScrollView
android:id="#+id/start_root"
android:layout_height="wrap_content"
android:layout_width="fill_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/fragment_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/page_title_text"
android:textSize="32sp"
android:paddingBottom="5dp"
android:layout_centerHorizontal="true" />
<TextView
android:id="#+id/fragment_intro"
style="#style/wizard_intro_style"
android:layout_below="#+id/fragment_title" />
</RelativeLayout>
</ScrollView>

progressbar on top of Button in relative layout issue in Android Studio

Ok this is a weird one I hope someone can explain to me.
I have a custom button layout which creates a button with a circular progress bar in the middle of the button. My XML code is below. What I can't work out however is that the ProgressBar seems to be appearing behind the button. If I set the button background to anything other than transparent the progressbar cannot be seen. With the button background as transparent I can then see the ProgressBar but it still appears behind the button text. I was under the understanding that views appeared in the order they are added. I have even tried setting the view to be on top (view.bringToFront();) and I've tried removing the view and recreating it.
Why does the progressbar appear behind the button and what can I do to solve it?
Many thanks
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#android:color/holo_blue_bright"
android:padding="2dp">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="Button"
android:gravity="center"
android:textColor="#android:color/white"
android:singleLine="true"
android:clickable="false">
</Button>
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:layout_centerInParent="true"
android:visibility="visible"
/>
</RelativeLayout>
Code using the above layout
private void setupTableLayout(int NumberOfRows, int NumberOfButtons){
TableLayout.LayoutParams tableParams = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT);
TableRow.LayoutParams rowParams = new TableRow.LayoutParams(0, android.widget.TableRow.LayoutParams.MATCH_PARENT, 3f);
TableLayout tableLayout = (TableLayout) findViewById(R.id.thetablelayout);
tableLayout.removeAllViews();
for (int i = 0; i < NumberOfRows; i++) {
TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(tableParams);
RelativeLayout btnOneLayout = (RelativeLayout)getLayoutInflater().inflate(R.layout.custom_button, null);
RelativeLayout btnTwoLayout = (RelativeLayout)getLayoutInflater().inflate(R.layout.custom_button, null);
ProgressBar btnOneProgressBar = (ProgressBar)btnOneLayout.findViewById(R.id.progressBar);
ProgressBar btnTwoProgressBar = (ProgressBar)btnTwoLayout.findViewById(R.id.progressBar);
btnOneLayout.setLayoutParams(rowParams);
btnTwoLayout.setLayoutParams(rowParams);
Button btnOne = (Button)btnOneLayout.findViewById(R.id.button);
btnOne.setText("Btn 1, Row " + i);
btnOne.setId(1001 + i);
Button btnTwo = (Button)btnTwoLayout.findViewById(R.id.button);
btnTwo.setText("Btn 2, Row " + i);
btnTwo.setId(2001 + i);
setButtonClickListener(btnOneLayout, btnOneProgressBar);
setButtonLongClickListener(btnOneLayout, btnOneProgressBar);
tableRow.addView(btnOneLayout); //Add layout, instead of just Button
View adivider = new View(this);
adivider.setLayoutParams(new TableRow.LayoutParams(20, TableRow.LayoutParams.MATCH_PARENT));
adivider.setBackgroundColor(Color.TRANSPARENT);
// This bit of code deals with odd/even numbers of buttons.
if (((i + 1) * 2) < NumberOfButtons + 1) {
tableRow.addView(adivider);
tableRow.addView(btnTwoLayout);
} else {
tableRow.addView(adivider);
btnTwoLayout.setBackgroundResource(android.R.color.transparent);
tableRow.addView(btnTwoLayout);
}
tableLayout.addView(tableRow);
}
}
You are propably running this on android >= 5.0. In 5.0 they added elevation field for views. Elevation defines z-order of views in ViewGroup.
In that case button have non-zero elevation value and progress bar have zero value elevation.
Set elevation of progress bar to e.g. 10dp
<ProgressBar
...
android:elevation="10dp"/>
Put your button into another layout (best choice for this case is probably FrameLayout).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
... >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
... />
</FrameLayout>
<ProgressBar
android:id="#+id/progressBar"
... />
</RelativeLayout>
I can't tell you why exactly you get that effect, but I suppose that is a bug. Notice that if you replace Button with other view, for example TextView that problem doesn't exits. But when you change RelativeLayout to any other (tested with FrameLayout) this bug still appears. I guess it's going about background property and order of drawing or measurement in any layout.
try using FrameLayout like this
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="#android:color/holo_blue_bright"
android:padding="2dp">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:text="Button"
android:gravity="center"
android:textColor="#android:color/white"
android:singleLine="true"
android:clickable="false">
</Button>
<ProgressBar
android:layout_gravity="center"
android:id="#+id/progressBar"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="#android:color/transparent"
android:layout_centerInParent="true"
android:visibility="visible"
/>
</FrameLayout>
See this link
Generally, FrameLayout should be used to hold a single child view,
because it can be difficult to organize child views in a way that's
scalable to different screen sizes without the children overlapping
each other. You can, however, add multiple children to a FrameLayout
and control their position within the FrameLayout by assigning gravity
to each child, using the android:layout_gravity attribute.
Child views are drawn in a stack, with the most recently added child on top.
By adding marginTop you can do that.. otherwise you can change the structure of button and progress bar...
<linearLayout android:orientation="horizontal" ... >
<ImageView
android:id="#+id/thumbnail"
android:layout_weight="0.8"
android:layout_width="0dip"
android:layout_height="fill_parent"
>
</ImageView>
<TextView
android:id="#+id/description"
android:layout_marginTop="-20dip"
android:layout_weight="0.2"
android:layout_width="0dip"
android:layout_height="wrap_content"
>
</TextView>
this code is working fine for me :D

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