I tried to implement Pull to Refresh in my app.
I wrapped my xml code with android.support.v4.widget.SwipeRefreshLayout and it's working, but the GUI doesn't look good.
When I pull down, I should see the regular animated circle icon with my defined colors, right?, but I see it as a blank circle and not a turning one with colors as it should.
Furthermore, I can't "play" with it and even hold it for a while after I pull it, it goes down for one second (do what it does) and then disappears.
I think it's because I'm not using ListView but LinearLayout instead.
What do you think?
Code:
XML:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/swipe">
<LinearLayout
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:orientation="vertical"
android:layout_width="match_parent"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#7B68EE"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".HomeActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/loin"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/welcome"
android:textColor="#B0C4DE"
android:id="#+id/welcomeBackID"
android:layout_alignParentTop="true"
android:layout_alignRight="#+id/webViewCurren"
android:layout_alignEnd="#+id/webViewCurren" />
....
</android.support.v4.widget.SwipeRefreshLayout>
Java:
public class HomeActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
SwipeRefreshLayout mSwipeRefreshLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe);
mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_green_light,
android.R.color.holo_blue_bright,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
mSwipeRefreshLayout.setOnRefreshListener(this);
#Override
public void onRefresh() {
Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show();
sharedPrefEditor.putString("coordinateX", "34.7");
sharedPrefEditor.putString("coordinateY", "32.5");
sharedPrefEditor.putString("saved", "false");
sharedPrefEditor.commit();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
}, 3000);
}
}
Try changing the SwipeRefreshLayout color scheme.
swipeRefreshLayout.setColorSchemeColors(
Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);
Also, the SwipeRefreshLayout will be visible only till onRefresh() completes its execution.
Related
Note: These are randomly generated addresses
Hey Guys, Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I color coded my layouts to see if the sizes where a problem, but I dont think they are since my orange layout is plenty big to hold my two entries. Am I using the wrong layouts for this kind of application? I would appreciate any help!
Here is my translation code:
frameLayout.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
And my layout file:
<android.support.v4.widget.SwipeRefreshLayout 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/swipeLayout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:id="#+id/frameLayoutParent"
android:background="#android:color/holo_green_dark">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:background="#android:color/holo_green_light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:background="#android:color/holo_orange_light">
<Button
android:text="Add New Address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/addNewAddress"
android:maxHeight="20dp" />
</LinearLayout>
<ListView
android:paddingTop="50dp"
android:minWidth="25px"
android:minHeight="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:maxHeight="300dp"/>
</FrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editSearch"
android:hint="Search ZipCodes"
android:textColor="#000"/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
EDIT:
Here is my OnOptionsItemSelected Code, where my animation is triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.action_search:
//search icon has been clicked
if (isAnimating)
return true;
else
{
if (animateBool)
{
//list view is up
animation anim = new animation(myListView, myListView.Height - editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartDown; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndDown;
classSwipeRefresh.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
}
else
{
animation anim = new animation(myListView, myListView.Height + editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartUp; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndUp;
classSwipeRefresh.Animate().TranslationYBy(-editSearch.Height).SetDuration(500).Start();
}
animateBool = !animateBool;
return true;
}
default:
return base.OnOptionsItemSelected(item);
}
}
Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I use your code to test, but I have no problem when translating by Y in SwipeRefreshLayout__Refresh event.
public class MainActivity : AppCompatActivity
{
string[] items;
ListView listview1;
SwipeRefreshLayout swiplayout;
FrameLayout framelayout;
EditText edittext;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
listview1 = FindViewById<ListView>(Resource.Id.myListView);
swiplayout = FindViewById<SwipeRefreshLayout>(Resource.Id.swipeLayout);
framelayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
edittext = FindViewById<EditText>(Resource.Id.editSearch);
swiplayout.Refresh += Swiplayout_Refresh;
items = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
listview1.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);
}
private void Swiplayout_Refresh(object sender, EventArgs e)
{
framelayout.Animate().TranslationYBy(edittext.Height).SetDuration(500).Start();
}
}
This is my screenshot:
If you want to filter ListView, I suggest you can use SearchView in Toolbar to filter listview data, please take a look this sample:
https://github.com/Cheesebaron/SearchView-Sample/tree/master/SearchViewSample
I use android.support.v4.widget.SwipeRefreshLayout in my Android app. It wraps a ListView. The content of the list view is downloaded from a server.
A progress view is shown when user swipes down in order to reload data from server. The progress view looks like a piece of circle that grows and shrinks during the animation. It seems that the style of this progress view cannot be customized much. However, I am fine with its built-in style.
I also show the same progress animation during initial data loading. This can be achieved by calling mySwipeRefreshLayout.setRefreshing(true). That's perfectly OK too.
However, I would like to show the same progress indication through the whole app. Consider e.g. another activity that looks like a form with submit button. There is neither a ListView nor a SwipeRefreshLayout in this form activity. Some progress indication should be displayed while the submitted data are transferred to the server. I want to show a progress bar with the same animation like in SwipeRefreshLayout.
Is there a simple and clean way to have the same progress indicator for both a SwipeRefreshLayout and a form activity that does not contain any list view and refresh layout and does not support any swipe gesture?
Thanks.
However, I would like to show the same progress indication through the
whole app. Consider e.g. another activity that looks like a form with
submit button. There is neither a ListView nor a SwipeRefreshLayout in
this form activity. Some progress indication should be displayed while
the submitted data are transferred to the server. I want to show a
progress bar with the same animation like in SwipeRefreshLayout.
yes you can use SwipeRefreshLayout to show like ProgressDialog when button click. check below.
i have added SwipeRefreshLayout inside my layout file still there is not ListView or ScrollView. just like below
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="niu.com.djandroid.jdroid.androidstack.MainActivity"
tools:showIn="#layout/activity_main">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/activity_main_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<SeekBar
android:id="#+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="54dp" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
now in my activity i used AsyncTask to show SwipeRefreshLayout. also use mSwipeRefreshLayout.setOnRefreshListener(null) to stop swipe gesture.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
mSwipeRefreshLayout.setOnRefreshListener(null);
((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// mSwipeRefreshLayout.setRefreshing(true);
// call AsyncTask
new LongOperation().execute("");
}
});
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
// stop mSwipeRefreshLayout
mSwipeRefreshLayout.setRefreshing(false);
}
#Override
protected void onPreExecute() {
// start mSwipeRefreshLayout
mSwipeRefreshLayout.setRefreshing(true);
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
EDITED:15/02/20
After 4 year, Here is great explanation on android developer site
mSwipeRefreshLayout.setOnRefreshListener(null)
didn't work for me, so I made this method to enable and disable refreshing.
private void setToRefresh(boolean refresh) {
if (refresh) {
mSwipeRefreshLayout.setEnabled(true);
mSwipeRefreshLayout.setRefreshing(true);
} else {
mSwipeRefreshLayout.setRefreshing(false);
mSwipeRefreshLayout.setEnabled(false);
}
}
I am using a SwipeRefreshLayout and an EnhancedListView to combine them like GMAIL-App. When I start to swipe horizontal I am still be able to swipe vertical. In this case the animation from EnhancedListView stuck and do not reset or swipe till the end if I do not complete the vertical (SwipeRefreshLayout) swipe.
I can see, that first pull to refresh and then swipeToDismiss does not work. Only first swipe and then refresh. So i guess it is about beeing a parent element.
Possible Solution i thought about:
Check for horizontal scrolling and disable SwipeRefreshLayout with swipeL.setEnabled(false); When finished swipeL.setEnabled(true); But I can not find where to disable and enable it.
My Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#0A756E"
android:gravity="center" >
<LinearLayout
android:id="#+id/ll_archiv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/greenbox" >
<TextView
android:id="#+id/tv_archiv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="#string/archiv"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
</LinearLayout>
</RelativeLayout>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<de.android.voucheroo.utils.EnhancedListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/footer"
android:layout_alignParentTop="true"
android:descendantFocusability="blocksDescendants" >
</de.android.voucheroo.utils.EnhancedListView>
</android.support.v4.widget.SwipeRefreshLayout>
My Code:
swipeL = (SwipeRefreshLayout) getActivity().findViewById(
R.id.swipe_container);
ll_archiv = (LinearLayout) getActivity().findViewById(R.id.ll_archiv);
tv_archiv = (TextView) getActivity().findViewById(R.id.tv_archiv);
elv = (EnhancedListView) getActivity().findViewById(android.R.id.list);
elv.setDismissCallback(new OnDismissCallback() {
#Override
public Undoable onDismiss(EnhancedListView listView,
final int position) {
try {
final Object vouch = voucher.get(position);
voucher.remove(position);
adapter.notifyDataSetChanged();
return new EnhancedListView.Undoable() {
#Override
public void undo() {
voucher.add(position, vouch);
adapter.notifyDataSetChanged();
}
// Return a string for your item
#Override
public String getTitle() {
return "foo";
}
// Delete item completely from your persistent storage
#Override
public void discard() {
[...];
}
};
} catch (Exception e) {
Log.w("ELV_EXCEPTION", e.getMessage());
e.getStackTrace();
return null;
}
}
});
swipeL.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
[...]
swipeL.setRefreshing(false);
}
});
// Handler
elv.enableSwipeToDismiss();
elv.setSwipingLayout(R.id.ll_parent);
elv.setUndoStyle(UndoStyle.MULTILEVEL_POPUP);
Nowsaday I know the answer of my own question. It is not a problem with my code, it is a problem with SwipeRefreshView.
There is a similar question with the same Problem I found here: SO-Answer
I'm using SwipeRefreshListener from the support libraries. I am calling setRefresh from onPreExecute and onPostExecute of my AsyncTask. However, nothing changes, there is no animation. Is there something that I'm missing? Are there certain setup parameters I need to set in order for it to work properly?
This has worked for me, see more here: http://antonioleiva.com/swiperefreshlayout/
SwipeRefreshLayout: The layout
you only need to decorate the swipable content (probable the whole layout) with this new layout. This view must be scrollable, such a ScrollView or a ListView. As a simple example:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center"/>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
The code
We just need to get the layout, and assign some colours and the listener. The refreshing listener is a post delayed handler.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
#Override public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
//Please check this answers it hepls me :
//SwipeRefreshLayout setRefreshing() not showing indicator initially
//especially this
mSwipeRefreshLayout.post(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});
In my app I want when the screen dims to add a layer above everything so when the users taps on screen the dimness will be gone and then he can use the app. If I dont do this when the screen is dimmed and the user taps on screen he will activate something in the app.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<!-- The main content view -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="#+id/radio_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</FrameLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</FrameLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/disc"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical" />
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ffffff"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="10dp" />
this is my layout. When the screen dims i make the disc visible and when the user touches something on screen I make it View.gone. The problem is that the click on the disc is also activating something on my content frame fragment.
Is there a way to make it now happen? I want the click to activate only the disc onclickhandler not anything else. Or is there any other way to do this?
So I figured out how to do this. The trick is to have an onclickListener on the view itself. I was just making it disappear while I had to also get the click.
private final Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
runOnUiThread(new Thread(new Runnable() {
#Override
public void run() {
disconnect.setVisibility(View.VISIBLE);
}
}));
}
};
private static final Handler disconnectHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
}
};
public void resetDisconnectTimer() {
disconnectHandler.removeCallbacks(disconnectCallback);
disconnectHandler.postDelayed(disconnectCallback, 3000);
}
public void stopDisconnectTimer() {
disconnectHandler.removeCallbacks(disconnectCallback);
}
#Override
public void onUserInteraction() {
resetDisconnectTimer();
}
#Override
public void onResume() {
super.onResume();
resetDisconnectTimer();
}
and in onCreate i have this
disconnect = findViewById(R.id.disc);
disconnect.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
disconnect.setVisibility(View.GONE);
}
});
in my previous attempt i was making the disconnect "gone" inside the handler. Now i have an onclick listener on this.