Horizontal scroll and focus on the last number in a TextView - java

I am doing a calculator app.
I have a TextView where the user writes the numbers to elaborate.
The TextView is inside a HorizontalScrollView. The HorizontalScrollView is inside a vertical LinearLayout. The TextView is single line, and, when the user writes a long number, the number comes out of the screen.
The TextView should follow the last number added by the user, so he can view the last numbers added without scrolling the screen. I don't want an autoscroll function that repeat the scroll every second, i only want focus on the last number added.
This is the TextView
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/numberDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="0dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="16dp"
android:hint="0"
android:scrollHorizontally="true"
android:maxLines="1"
android:layout_gravity="right"
android:textSize="70sp" />
</HorizontalScrollView>

Try this:
In your activity create variables for your scroll view and text view:
TextView textView;
HorizontalScrollView scrollView;
Initialize them in onCreate():
scrollView = (HorizontalScrollView) findViewById(R.id.scrollView); // Add this id to xml
textView = (TextView) findViewById(R.id.numberDisplay);
Each time you update text of your text view update scroll position of the scroll view:
scrollView.scrollTo(textView.getRight(), textView.getTop());
Update:
I realized that if you call textView.setText(...) and then immediately scrollView.scrollTo(...) it does not work since text view size is not updated immediately. You should rather update scoll position like this:
scrollView.post(new Runnable() {
#Override
public void run() {
scrollView.scrollTo(textView.getRight(), textView.getTop());
}
});

Related

Custom Android Spinner Layout Issue

I am customizing an android Spinner Widget. I am trying to use different background colors against the list items. This is working, but when there are more items in the spinner control, the list items are not occupying the full space horizontally, thus showing white space on the popup view.
For small number of items, it is working fine.
I have tried custom and default Layout customizations.
JAVA Custom Spinner View Code
#Override
public View getView(int pos, View view, ViewGroup parent)
{
LayoutInflater objInflater = LayoutInflater.from(context);
view = objInflater.inflate(R.layout.spinner_item_colored, null);
LinearLayout llOption = (LinearLayout) view.findViewById(R.id.llOption);
TextView tvOption = (TextView) view.findViewById(R.id.tvOption);
if (alDefects.get(pos).sNature.equalsIgnoreCase("1"))
llOption.setBackgroundColor(getResources().getColor(R.color.majorDefect));
else if (alDefects.get(pos).sNature.equalsIgnoreCase("2"))
llOption.setBackgroundColor(getResources().getColor(R.color.criticalDefect));
else
llOption.setBackgroundColor(getResources().getColor(R.color.minorDefect));
tvOption.setTextColor(getResources().getColor(R.color.white));
tvOption.setText(alDefects.get(pos).sDefect);
return view;
}
XML Code:
<LinearLayout
android:id="#+id/llOption"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_weight="1"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_margin="0dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="#+id/tvOption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|left"
android:singleLine="false"
android:textColor="#444444"
android:textSize="13dp" />
I want the spinner popup to use full available width for Background color when there is a scrollbar.
Please click this Link to see the Sample Output
When you use weight you should set android:layout_width="0dp"

how to get TextViews from .xml to Java file

<TableRow
android:id="#+id/Row3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<TextView
android:id="#+id/cell31"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:textSize="50sp"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="#drawable/back"
android:onClick="cellClick"
android:clickable="true"/>
<TextView
android:id="#+id/cell32"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:textSize="50sp"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceLarge"
android:background="#drawable/back"
android:onClick="cellClick"
android:clickable="true"/>
.... this is 5x5 row column table. with 25 cells in it.
My .xml file looks like this. I have bunch of rows in LinearLayout contains TableLayouts which contains TextViews as cells. I am making a basic game with them.
I am trying to assign each cell from .xml to TextView array in .java file. But i can't figure out how to make it. I need to change color of each cell based on some algorithm i made so i want to access of cells.
private TextView colorBoard[][];
this is my .java array.
I can check if they are clicked with
public void cellClick(View v) {
TextView cell = (TextView) findViewById(v.getId());
switch (cell.getId()) {
case R.id.cell11:
xloc = 0;
break;
case R.id.cell12:
xloc = 1;
break ;
...rest of cells
But i only can assign which cell clicked at moment.In my game color of cells change differently. Not the one you just clicked. Assume you clicked 1x3 and 4x4 may change colors.
I'm new to android and this is my first project so sorry if i'm missing something basic.
I think you should use ListView instead of TextView. In ListView you can use an array for assigning those things where-ever you want to use them.
You can create layout file like this:
<ListView>
android:weight="match_parent"
android:height="match_parent"
android:id="+id/lst_view"
</ListView>
And Your Java Code looks like this
String[] array={"stack","queue","arraylist"};
ListView lst;
//In onCreate function
lst=(ListView)findViewById(R.id.lst_view);
ArrayAdapter<String> adpt=new ArrayAdapter<String>(this,R.layout.what_ever_your_xml,array);
lst.setAdapter(adpt);
//function of listview
//arrayadapter is used for converting string type array into listview
lst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String s;
s=((TextView)view).getText().toString();
Toast.makeText(getApplicationContext(), s,Toast.LENGTH_LONG).show();
}
});
If you want to assign values to TextView Array.
Then do it like this in oncreate method after setContentView
colorBoard[0][0] = (TextView) findViewById(R.id.cell11);
colorBoard[0][1] = (TextView) findViewById(R.id.cell12);
You can use findviewbyId to get the TextView from xml to Java.
Suppose if you want to access cell44 when you tap on cell11, then you could do something like this.
public void cellClick(View v) {
TextView cell = (TextView) findViewById(v.getId());
switch (cell.getId()) {
case R.id.cell11:
xloc = 0;
colorBoard[0][0].setBackground()//As you wish
break;
case R.id.cell12:
xloc = 1;
break ;
...rest of cells
Once you have access to cell44 you can set the background color or any other properties to it.

Textview still visible even if listview gets an item

I have an imageview, 2 textviews that needs to appear when the listview is empty. I want the 2nd textview to be clickable
as well. Here is my code -
<ImageView
android:id="#android:id/empty"
android:layout_width="120sp"
android:layout_height="130sp"
android:layout_gravity="center"
android:gravity="center"
android:src="#drawable/flower" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingTop="120sp"
android:text="Warning" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingTop="200sp"
android:text="Click Me" />
The image view disappears when the list view gets an item but the text views are still visible.
How can I make these 2 textviews disappear when the list view gets an item? Also how can I make my second text view clickable?
You can easily make them invisible. In your activity do this when you add an item to the list:
TextView tvXY = (TextView) findViewById(R.id.[TheIdHere]);
tvXY.setVisibility(View.GONE);
In your xml file you will have to change the id of the textviews too. Choose different ids for both of them. You can change the id by editing this:
#android:id/empty
To something like this.
#+id/[TheIdHere]
To make textView clickable you can setOnClickListener to that textView like this:
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});

ListView with Load More Button and Circle ProgressBar

I spent an hour trying to add "Load More" Button and indeterminate ProgressBar to the footer of my ListView.
The supposed scinario works like this:
When the button is clicked, ProgressBar is shown while AsyncTask is downloading 20 items. when the items are inserted to the ListView, the ProgressBar dismisses and the Button appears again in the footer.
I come to the following solution and would be nice if you have better solution:
layout/progress_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
/>
And assuming you have the following fields in the Activity:
private ListView listview;
private Button loadMoreButton;
private ProgressBar progressBar;
after preparing your list view add the footer like this, (at the end of the activity.onCreate()):
loadMoreButton = new Button(this);
loadMoreButton.setText("Load More");
progressBar = (ProgressBar) LayoutInflater.from(this).inflate(R.layout.progress_bar, null);
loadMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//downloadItems();
listview.removeFooterView(loadMoreButton);
listview.addFooterView(progressBar);
}
});
When the data is ready (either first page or subsequent pages), call the following after adapter update.
//adapter.notifyDataSetChanged();
listview.removeFooterView(progressBar);
listview.addFooterView(loadMoreButton);
If you have better solutions, please share it in the answers.
Instead of removing and adding a view as footer.. you can have both button and progressbar in the same footer view and make visibility VISIBLE and Visibility GONE according to the requirement.
I came to a solution without adding/removing the footer. Just put the two views (Load More Button and ProgressBar) in LinearLayout. Add the linearlayout as listview footer for first time only. Then change between the button and progressbar by changing visibility property.
Here is the updated code:
layout/list_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/load_more_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="Load More"/>
<ProgressBar android:id="#+id/load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:indeterminate="true" />
</LinearLayout>
call this method at the end of Activity.onCreate() to add footer and handle button click (load data, hide button and show progress).
private void prepareListFooter() {
View view = (View) LayoutInflater.from(this).inflate(R.layout.list_footer, null);
loadMoreButton = (Button) view.findViewById(R.id.load_more_button);
progressBar = (ProgressBar) view.findViewById(R.id.load_progress);
listview.addFooterView(view);
loadMoreButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//downloadMore();
loadMoreButton.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
}
});
}
also this code after adapter change to show the button and hide the progress.
adapter.notifyDataSetChanged();
loadMoreButton.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);

Views are invisible after they was added into ViewGroup

I'm adding views programatically into FrameLayout:
public class PixelGridView extends FrameLayout {
...
public void addViewWithoutCoords(TableView view, int column, int row) {
float x = column * mCellSideSize;
float y = row * mCellSideSize;
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
view.setLeft(0);
view.setTop(0);
view.setX(x);
view.setY(y);
view.setVisibility(VISIBLE);
addView(view);
}
...
}
However, all they are somehow invisible. getChildCount() returns count with all of them. getVisibility() for each added view also returns VISIBLE.
I can drag'n'drop such views from another ViewGroup into my Framelayout and when I do this, all earlier added views become visible.
view layout file:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/ivTable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<EditText
android:id="#+id/ivTableName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#color/style_table_grey"
android:textColor="#android:color/white"/>
</RelativeLayout>
Even If I add new view without drag everything become visible.
The item view of the FrameLayout and RelativeLayout can be overlapping. If two item views are in the same positions of FrameLayout, the first loaded item will be covered by the later item.
Try turn on the show layout bounds in developer option of your android devices,and find the position of your item.

Categories

Resources