I am trying to display a textual histogram into a TextView in Android Studio but I don't want it to break the line of characters and separate them onto two lines, because it obviously ruins the histogram. I have the text set to resize itself in order to fit into the text box when I have more and more lines, but I want to make the size scale to the longest line specifically, that way they are all on a single line.
Here is what the histogram is showing, rather than adjusting the line size
<TextView
android:id="#+id/histogramTextbox"
android:layout_width="0dp"
android:layout_height="453dp"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:autoSizeMaxTextSize="80sp"
android:autoSizeMinTextSize="12sp"
android:autoSizeStepGranularity="2sp"
android:autoSizeTextType="uniform"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/totalRollsText" />
Here is what I have in my textview XML in order to scale the font size.
For whatever reason, you have to set android:maxLines too in order to get the autosizing to work properly (and it's a good idea to use app:autoSize* instead of android:autoSize* to support API levels < 26 or if you are using AppCompat components).
There are a lot of details about getting this right here - some key takeaways in addition to using maxLines are: do not use android:singleLine, and do not use wrap_content for either width or height.
Demo Use
<TextView
android:id="#+id/histogram_text"
android:layout_width="0dp"
android:layout_height="400dp"
android:layout_marginStart="36dp"
android:layout_marginEnd="36dp"
android:maxLines="5"
app:autoSizeMaxTextSize="20sp"
app:autoSizeMinTextSize="4dp"
app:autoSizeStepGranularity="1sp"
app:autoSizeTextType="uniform"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/get_text"/>
If the max lines changes dynamically, you can set it in code instead, like this
private fun expandHistogram() {
var demoHist = "(01): #\n"
demoHist += "(02): ##\n"
demoHist += "(03): ##############\n"
demoHist += "(04): " + "#".repeat(h) + "\n"
demoHist += "(05): ##############\n"
binding.histogramText.text = demoHist
binding.histogramText.maxLines = 5
h += 5
}
Create constraintlayout as parent of a textview. Set your textview width to match constraint. You are good to go.
Related
I get the text Size from the TextView and store in DB and
Later I am trying to set the value back. But I am getting different size on the display.
Whats the correct way to do this ?
|*| Get Text Size from Text View Store in DB :
int txtSyzVar = namTextViewVar.getTextSize();
|*| Later Fetch Back and Set :
namTextViewVar.setTextSize(txtSyzVar);
Also tried
namTextViewVar.setTextSize(TypedValue.COMPLEX_UNIT_SP, txtSyzVar);
namTextViewVar.setTextSize(TypedValue.COMPLEX_UNIT_DIP, txtSyzVar);
Use GridLayout on xml for aligned elements.
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/GridLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="2"
android:rowCount="2"
android:orientation="horizontal"
tools:context=".GridXMLActivity" >
</GridLayout>
When I use the autocompletetextview everything works fine except it keeps switching between two positions: the correct one right below the textview and quite a ways lower. It starts wrong, but almost immediately moves to the correct position. However this is very annoying when typing or backspacing as it happens for every letter. I am using android studio.
It appears as if two events are simultaneously trying to decide the layout. Sometimes it will stick in one position or the other.
**I slowed down the filtering process with a custom adapter and it looks like when text is entered it moves into the incorrect position, and then when the filtering is done it moves back into the correct position.
Incorrect
Correct:
java (in OnCreate())-
String[] drugs = new String[]{"Nexium","Amoxicillin","LEVOCETIRIZINE DIHYDROCHLORIDE", "Advil", "Advair Diskus", "Daraprim"};
AutoCompleteTextView drugNameAutoComplete = ((AutoCompleteTextView) findViewById(R.id.drugNameEditText));
drugNameAutoComplete.setAnimation(null);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,drugs);
drugNameAutoComplete.setAdapter(adapter);
And the layout code-
<AutoCompleteTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/drugNameEditText"
android:enabled="true"
android:singleLine="true"
android:layout_below="#+id/lookingForView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:dropDownVerticalOffset="50dp"
android:hint="#string/drug_name" />
If I remove the dropDownVeticalOffset I get flickering between the correct value and this-
To change this position use dropDownAnchor attribute and reference another view id.
(view under autocomplete)
android:dropDownAnchor
View to anchor the auto-complete dropdown to. If not specified, the text view itself is used.
and you have many attributes for dropdown..
You better to use implement Filter to autocomplete adapter and pass the entered text from OnQueryTextListener of autocomplete, and set the selected text by calling adapter.getitem.
Change your xml to-
<AutoCompleteTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/drugNameEditText"
android:enabled="true"
android:singleLine="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
**android:dropDownVerticalOffset="0dp"**
**android:dropDownAnchor="#id/drugNameEditText"**
android:hint="drug" />
Did you by any chance use the same id on the other AutoCompleteTextView? I can reproduce the behaviour you describe by including two views with the same id.
I had the same problem on my end with the newest API for some reason. I solved the problem by explicitly setting dropDownAnchor, dropDownVerticalOffset, and dropDownHeight in both the XML and the onTextChanged event.
Edit: After some checking, it seems this behavior is INCONSISTENT BETWEEN APIs starting with Marshmallow (API 23). Try changing your code to the following:
final float scale = context.getResources().getDisplayMetrics().density;
int verticalOffsetDP;
int dropDownHeightDP = (int) (200 * scale + 0.5f);
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
if (currentApiVersion < Build.VERSION_CODES.M)
{
// Prior to Marshmallow DropDownVerticalOffset works as expected
verticalOffset = 0;
}
else
{
// Marshmallow has some weird DropDownVerticalOffset behavior so we have to compensate
verticalOffset = (int) (50 * scale + 0.5f);
}
AutoCompleteTextView drugNameAutoComplete = ((AutoCompleteTextView)findViewById(R.id.drugNameEditText));
drugNameAutoComplete.setAnimation(null);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,drugs);
drugNameAutoComplete.setAdapter(adapter);
drugNameAutoComplete.setDropDownAnchor(R.id.drugNameEditText);
drugNameAutoComplete.setDropDownVerticalOffset(verticalOffsetDP);
drugNameAutoComplete.setDropDownHeight(dropDownHeightDP);
And your XML to the following:
<AutoCompleteTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/drugNameEditText"
android:enabled="true"
android:singleLine="true"
android:layout_below="#+id/lookingForView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:dropDownVerticalOffset="50dp"
android:dropDownAnchor="#id/drugNameEditText"
android:dropDownHeight="200dp"
android:hint="#string/drug_name" />
Note that you have to calculate DP based on screen dimensions in code. I got the code example from the excellent accepted response in this thread: Android and setting width and height programmatically in dp units
The reason you have to set dropDownHeight as well is because otherwise Android has a behavior to push it up to the top of the screen if the list extends beyond the height boundaries of the view, further complicating the moving-around issues. If you actually don't mind this (some people don't, depends on your view setup), you can remove dropDownHeight from both programmatic and XML.
I should note that these changes still don't make things EXACTLY the same between Marshmallow and other APIs. Looks like there is still a few pixels difference. But it gets pretty close.
I had the same problem and too many hours later I've found the solution.
You should change:
android:layout_width="wrap_content" to android:layout_width="match_parent"
I hope it works for you too.
Here is the xml (activity_matches.xml) that displays the output in the screen shot below in an EditText object named txaMatches:
<EditText
android:id= "#+id/txaMatches"
android:text= ""
android:scrollbars= "vertical"
android:layout_below= "#+id/pattern"
android:textColor= "#color/yellow_foreground"
android:textSize= "#dimen/matches_text"
android:focusable="false"
android:inputType="textMultiLine"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd= "true"
tools:ignore= "LabelFor"
android:typeface="monospace"
android:focusableInTouchMode="false"
android:paddingEnd="#dimen/matches_padding"
android:paddingStart="#dimen/matches_padding"
/>
I would like the contents of this multiline EditText object to scroll smoothly with acceleration if the user swipes inside it.
Here's how I fill txaMatches (using doInBackground). This is the only place in Java code that I refer to it (of course I also define and initialize it in Java):
protected void onProgressUpdate(String... progress)
{
for (int i = 0; i < progress.length; i++)
if(progress[i].length() > 1) MatchesActivity.txaMatches.append("\n" + progress[i]);
else MatchesActivity.showLetter("Reading " + progress[i].charAt(0));
}
Is this an easy change to be made in xml?
Should I be using a ListView? Should the EditText be inside a ListView?
Am I going to have to write some Java code?
Given the small amount of code I've provided, I don't expect many details. Just an overview of what to Google would be a good start.
Pretty easy (thanks to Fllo's THIRD link). (The first was no help; the second focuses on Java code and the ScrollView class and is more involved than the third, which focuses on xml and was perfect for my situation (and required only changing the type of txaMatches to TextView):
start of new code
<ScrollView
android:layout_alignParentStart="true"
android:layout_alignParentEnd= "true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
end of new code except for closing tag
<TextView
android:id= "#+id/txaMatches"
android:scrollbars= "vertical"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
/>
</ScrollView>
I have a WebView in which I wish to render some content. But this WebView does not show a single character if the length of data I am showing reaches close to 5100 characters.
The WebView works perfectly fine if the length of data is less than 5000 characters.
I have tried to just pass simple data in the WebView similar to "abcde ....."
with < 5000 chars it would work fine.
with > 5100 chars it won't display a single character.
I have searched through the Internet to see if there are any limits for the amount of data that can be shown inside the WebView, but I don't seem to find anything.
Here is my Java Code.
myWebView = (WebView) findViewById(R.id.passage);
String data = "abcde ......."; // large number of characters > 5100.
myWebView.loadDataWithBaseURL(URL, data, "text/html", null,null);
I have tried myWebView.loadData(data, "text/html", null); as well instead of using the loadDataWithBaseURL function, but that has not helped.
Here is the XML that I am using.
<ScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fadeScrollbars="false"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="0" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/passage"
android:textColor="#color/red"
android:textSize="18px" />
<WebView
android:id="#+id/passage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadeScrollbars="false"
android:layerType="software"
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarFadeDuration="0" />
</LinearLayout>
</ScrollView>
Please help.
EDIT : To be more precise, if I render 5096 characters, it renders properly. If 5097 or more characters are attempted to be rendered, then nothing gets displayed. If I try to log the data variable in a file. All data gets logged, so its not a issue relating to proper data not being saved into string.
This was happening for me but at a much lower WebView content size. Loading 1506 characters via loadDataWithBaseURL worked just fine but when loading 1507 characters the entire WebView disappeared, including the background. (Yet I could still copy text from it.)
The workaround was to remove android:layerType="software" and fall back to the default hardware layerType.
I'm trying to program a disc golf scoring app on Eclipse for my android phone. I'd like to set it up for up to 6 players, but mostly 2 people will use it for a game. The data is being stored in a sqlite DB, and I am using a SimpleCursorAdapter to populate the data for holes that have already been scored. here is that code:
private void fillData() {
Cursor notesCursor = mDbHelper.fetchAllNotes();
startManagingCursor(notesCursor);
// Create an array to specify the fields we want to display in the list (only TITLE)
String[] from = new String[]{DiscGolfDbAdapter.KEY_HOLE,
DiscGolfDbAdapter.KEY_PAR,
DiscGolfDbAdapter.KEY_TOM_HOLE,
DiscGolfDbAdapter.KEY_TOM_GAME,
DiscGolfDbAdapter.KEY_CRAIG_HOLE,
DiscGolfDbAdapter.KEY_CRAIG_GAME,
DiscGolfDbAdapter.KEY_TOMS_POSITION,
DiscGolfDbAdapter.KEY_SKIP_PLAYER
};
// and an array of the fields we want to bind those fields to (in this case just text1)
int[] to = new int[]{R.id.schole, R.id.scpar, R.id.scth, R.id.sctg, R.id.scch, R.id.sccg, R.id.sctp,
R.id.skip};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter notes =
new SimpleCursorAdapter(this, R.layout.hole_info, notesCursor, from, to);
setListAdapter(notes);
}
From searching the internet I've found what I think are two posibilities that SHOULD work, but do not.
First I've tried the XML Attribute: android.visibility. It looks like this in the PORTION of the view that I am trying to "test" hide:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android.visibility="GONE">
<TextView android:id="#+id/scch"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/sccg"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
</LinearLayout>
I have tried it with "GONE", "Gone" and "gone". NONE of them work in the eclipse emulator OR on my actual phone. So, there is no point in trying to parameterize this attribute.
Next I've tried setting the XML attribute for android:layout_height to "0dip". This indeed works in the emulator and on my phone WHEN IT IS HARDCODED.
Then I moved to the next logical step (as I see it), storing a parameter in the DB so that I can "show" or "not show" the item DEPENDING on conditions within the record. So, I've stored a field in the DB with two values "0dip" and "wrap_content". I pass these to the layout as shown in the java above as R.id.skip. I've also added these to the output just to audit that they are really there. Here is that XML:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="#+id/skip">
<TextView android:id="#+id/scch"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
<TextView android:id="#+id/sccg"
android:layout_width="45dip"
android:gravity="right"
android:textSize="25sp"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView android:id="#+id/skip"
android:gravity="center"
android:layout_width="315dip"
android:textSize="10sp"
android:layout_height="wrap_content"/>
In the above test, both via the Eclipse emulator and my android phone, the last TextView confirms that the DB contains either "0dip" or "wrap_content", BUT the LinearLayout with:
android:layout_height="#+id/skip">
behaves as if it were "0dip" ALL of the TIME. In other words, I cannot PROGRAMMATICALLY" affect the XML attribute for android:layout_height.
If there is a better/more standard way of accomplishing what I am trying to do, please share - BUT BE CLEAR. I am new, so CODE EXAMPLES wwill work best for me.
May 29th - It seems to me (based on testing) that you cannot alter layout attributes for the layout specified in this code:
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.hole_info,
notesCursor, from, to);
setListAdapter(notes);
Anything I try leads to some error ort another. So, I've seen examples of custom list adapters where these attributes are altered, so I'm trying to convert to a custom list adapter.
Why not do it in code?
LinearLayout ll = (LinearLayout)findViewById(R.id.your_layout_id);
ll.setVisibility(View.GONE);
Your XML layout code
android.visibility="GONE"
should be
android:visibility="GONE"
Change visible of a LinearLayout like Gabriel NeguĊ£ say:
LinearLayout ll =
(LinearLayout)findViewById(R.id.your_layout_id);
ll.setVisibility(View.GONE);
or change height of LinearLayout:
LinearLayout ll = (LinearLayout)findViewById(R.id.your_layout_id);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
lp.height = 0; // or lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
ll.setLayoutParams(lp);
What about this guy's solution http://enjoyandroid.wordpress.com/2012/03/12/customizing-simple-cursor-adapter/
Kind of worked for me.