ListView with Load More Button and Circle ProgressBar - java

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);

Related

How to add string at the bottom of a ScrollView

I would like to know how to add new strings at the bottom of a ScrollView every time I press a button.
For example at the beginning there is sentence1, press button, then sentence2 is under sentence1, press button, sentence3 is under sentence2, etc
I know how to make a scrollView and I have an array of strings to display:
final int[] sentences = new int[]{
R.String.sentence1,
R.String.sentence1,
R.String.sentence2,
R.String.sentence3,
R.String.sentence4
};
And I know how to make them appear one after another when a button is pressed (kind off replacing the previous one, like a TextSwitch but without the animation) :
if(nextSentenceId < sentences.length) {
officeOBSDialog.setText(sentences[nextSentenceId]);
++nextSentenceId;
}
Do you have any idea how I could manage to do that or what could I use? It occured to me that I could use like a layout inflator but I don't know how to put that to practice and where to put it. Thanks in advance
I recommend you to use ListView or RecyclerView.
https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
However, if you consistently want to use ScrollView cause your screen UI is simple. You can simply wrap a LinearLayout with vertical orientation by a ScrollView.
activity.xml
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout
android:id="#+id/lnContainer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- your button declaration -->
</LinearLayout>
</ScrollView>
In your activity java file, add new row programmatically by:
private int position=0;
final int[] sentences = new int[]{
R.String.sentence1,
R.String.sentence1,
R.String.sentence2,
R.String.sentence3,
R.String.sentence4
};
//inside onCreate() method
yourButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
TextView textView = new TextView(YourActivityClass.this);
textView.setText(sentences[position++]);
((LinearLayout)findViewById(R.id.lnContainer)).addView(textView);
}
});

Make New Button For Each JSON Object

I am trying to get my app to make a button for each item category from my JSON and set the button image and title in the app remotely. How can I do this so that I can add a new category from my database and in the app it will create a new button for that category with image and title?
Any help is much appreciated.
Unfortunately I don’t have much code at the moment to show.
You can simply take a horizontal/vertical linear layout in your xml that will act as a container. Put that LinearLayout in Horizontal or Vertical ScrollView like below.
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</HorizontalScrollView>
In your Activity :
for (int i = 0; i < yourArray.length(); i++) {
Button btn = new Button(this);
btn.setId(i);
btn.setTag(i);
btn.setText("Button " + (i+1));
btn.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_notifications_black_24dp), null, null, null);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("BTN", view.getTag().toString());
}
});
linearLayout.addView(btn);
}
Similarly, you can add any view you want in the LinearLayout either horizontally or vertically. Have a look at the attached screenshots.

How to use a ScrollView?

This is suppose to be a scroll view with all the content added from the Java code when response is received from the API.
The problem is that I can't find a way to display the information like this in a ScrollView. I tried using an ImageButton but I couldn't get the content in it then I tried using a Button but still couldn't achieve the desired effect please can someone suggest a way I could do this.
private Button makeButton(String targetName, final String i, LinearLayout.LayoutParams buttonLayoutParams) {
Button in = new Button(this);
in.setBackground(getResources().getDrawable(R.drawable.rectangle14));
in.setText(targetName);
in.setWidth(360);
in.setHeight(72);
in.setLayoutParams(buttonLayoutParams);
in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(HomeActivity.this,XSavingDetailsActivity.class);
myIntent.putExtra("i" ,i);
HomeActivity.this.startActivity(myIntent);
}
});
return in;
}
You should use a RecyclerView .Each and every component within the RecyclerView is a CardView . Also you should learn about Material Design.
Apart from the above some useful links:
https://developer.android.com/guide/topics/ui/layout/cardview.html
https://www.androidhive.info/2016/01/android-working-with-recycler-view/
https://medium.com/#nileshsingh/android-cardview-101-everything-you-should-know-5bbf1c873f5a
Just make the top-level layout a ScrollView:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1">
<!-- everything else -->
</TableLayout>

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
}
});

Android: NullPointerException being thrown on Button call?

I cannot figure out why but I keep getting E/AndroidRuntime(709): java.lang.NullPointerException at any point I try to call the buttons titled yes and no. The buttons are created in an xml layout and called using the findViewById method, a similar technique I've used in several properly working buttons in the same program. The only difference between these buttons and the rest is that their xml code is kept in a separate layout file that is not the main.xml.
If I only want to show the buttons and don't call them within the java code they will show up just as they should. The error occurs when I try to apply anything to them in the java code, such as setClickable() and setOnClickListener().
The code below outlines the creation of the button and layout in the xml and the java code shows a method that creates a popup when called.
Java Code:
private void getLogoutOption() {
LayoutInflater layoutInflater = (LayoutInflater)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.logoutoption, null);
final PopupWindow logoutoption = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button yes = (Button) findViewById (R.id.yes);
yes.setClickable(true);
yes.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
logoutoption.dismiss();
switchActivity(8);
}
});
Button no = (Button) findViewById (R.id.no);
no.setClickable(true);
no.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
logoutoption.dismiss();
}
});
logoutoption.showAsDropDown(search, 50, -30);
}
XML CODE:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent" >"
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/menu_default" >
<TextView
android:id="#+id/logoutmessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Are you sure you would like to logout?"
android:textColor="#color/gold" />
<Button
android:id="#+id/yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/logoutmessage"
android:layout_centerInParent="true"
android:text="YES"
android:textColor="#color/green" />
<Button
android:id="#+id/no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/logoutmessage"
android:layout_toRightOf="#id/yes"
android:text="NO"
android:textColor="#color/red" />
</RelativeLayout>
</RelativeLayout>
Button yes = (Button) findViewById (R.id.yes);
should be
Button yes = (Button) popupView.findViewById (R.id.yes);
By default findViewById() will be searching your content view for the view with the specified ID (e.g. if you used setContentView(R.layout.main), it will be searching through the main.xml structure for those views). If you're searching an inflated layout, you have to call findViewById() on that particular inflated layout.
Change:
Button yes = (Button) findViewById (R.id.yes);
Button no = (Button) findViewById (R.id.no);
To:
Button yes = (Button) popupView.findViewById (R.id.yes);
Button no = (Button) popupView.findViewById (R.id.no);
Hi The problem is you are getting id as you take in Activity.In Activity view created by setContentView(R.layout.main).In Your code you are inflating new view so you should use
Button yes = (Button)popupView.findViewById (R.id.yes);

Categories

Resources