Okay so I have a Tab view going inside of which I have a webview, a listview and a few other pages. I want to be able to do a SwipeRefreshLayout to refresh each item. I have this working on each page. But, when I scroll down in a webview I can't scroll back up. It triggers the refresh and rebuilds it. I'd like to be able to scroll up in my webview.
Layout stuff
<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="20px"
android:layout_weight="1"
android:nestedScrollingEnabled="true">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Splash$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/webView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:overScrollMode="ifContentScrolls"
android:nestedScrollingEnabled="false"/>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progressBar"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_centerVertical="false"
android:layout_centerHorizontal="true"
android:visibility="visible" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
The SwipeRefreshLayout is being used inside the fragment for my tabbed layout.
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container);
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);
swipeLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() {
#Override public void onRefresh() {
if(getArguments().getInt(ARG_SECTION_NUMBER) == 4 ) {
stringArrayList.clear();
new updatetheQueue().execute(ctx);
}
else {
swipeLayout.setRefreshing(false);
}
}});
You can use an OnScrollChangedListener to disable SwipeRefreshLayout when the WebView is not scrolled to the top.
// Only enable swipe to refresh if the `WebView` is scrolled to the top.
webView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (webView.getScrollY() == 0) {
swipeRefreshLayout.setEnabled(true);
} else {
swipeRefreshLayout.setEnabled(false);
}
}
});
Getting this working was very challenging. However there is a fairly simple modification that can be made to the layout XML to work around this. It means I can't update the webviews on swipe but thats okay.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Splash$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:overScrollMode="ifContentScrolls" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
<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">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Splash$PlaceholderFragment">
<ListView
android:id="#+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="false"
android:visibility="visible" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
you can make a class extend SwipeRefreshLayout and Override canChildScrollUp to sit scro
#Override
public boolean canChildScrollUp() {
// TODO Auto-generated method stub
return true; // if you want it to scroll up
// check if child Get To Top
//return false // if you want it to execute swipe down to refresh listener
}
If you are using the ViewPager and the tabs are Fragments, you can fix your WebViewFragment with this snippet:
private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
#Override
public void onStart() {
super.onStart();
swipeLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener =
new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (mWebView.getScrollY() == 0)
swipeLayout.setEnabled(true);
else
swipeLayout.setEnabled(false);
}
});
}
#Override
public void onStop() {
swipeLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
super.onStop();
}
More info in Android - SwipeRefreshLayout with empty textview.
this is how i solve the problem, hope it will help :
mWebView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if(mWebView.getScrollY() == 0){
mSwipeRefreshLayout.setEnabled(true);
}else{
mSwipeRefreshLayout.setEnabled(false);
}
}
});
In kotlin:
webView.viewTreeObserver.addOnScrollChangedListener {
binding.swipeRefreshLayout.isEnabled = webView.scrollY == 0
}
Related
Am trying to implement android SwipeRefreshLayout in my WebView app. When I swipe down it refreshes the page but it doesn't allow to scroll up and down anymore except the swipe.
I have tried some basic fix I found online but it still not working.
private WebView mywebview, handshakemywebview;
private SwipeRefreshLayout mySwipeRefreshLayout;
private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mywebview = findViewById(R.id.MainWebInterface);
handshakemywebview = findViewById(R.id.HandShakeWebInterface);
mySwipeRefreshLayout = this.findViewById(R.id.swipeContainer);
mywebview.loadUrl("https://example.com");
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
shopwebview.reload();
}
}
);
}
#Override
protected void onRestart(){
super.onRestart();
mySwipeRefreshLayout.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (mywebview.getScrollY() == 0) {
mySwipeRefreshLayout.setEnabled(true);
} else {
mySwipeRefreshLayout.setEnabled(false);
}
}
});
}
#Override
protected void onPause(){
super.onPause();
mySwipeRefreshLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
}
Layout XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#color/colorPrimary"
android:contentDescription="#string/activityLabel"
android:visibility="visible"
android:id="#+id/MainWebInterface"/>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<WebView
android:id="#+id/HandShakeWebInterface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="#color/colorPrimary"
android:visibility="gone" />
</RelativeLayout>
Add NestedScrollView in swiperefreshlayout. You could wrap webview in Swipe refesh layout like this
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/MainWebInterface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#color/colorPrimary"
android:contentDescription="#string/activityLabel"
android:visibility="visible" />
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Write OnRestart code in onResume.
Its because you are Adding addOnScrollChangedListener on Restart and onRestart is not called Always
I have a full image fragment. There is a RelativeLayout and LinearLayout in framelayout. LinearLayout contain viewpager.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linearLayoutViewpager">
<com.bogdwellers.pinchtozoom.view.ImageViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<RelativeLayout
android:id="#+id/relativelayoutforbuttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/save_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save" />
</RelativeLayout>
I want When user first open it it should only show image(Viewpager layout) and if user click on it that show other option like - share and save(RelativeLayout).
We can find this type of feature in facebook and whatsapp.
You can simply hide or unhide the relativeLayout's instance using setVisibility.(..) method on linearLayout or imageviewpager click.
layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linearLayoutViewpager">
<ImageViewPager
android:id="#+id/viewpager"
android:onClick="onPagerClick"
android:layout_width="200dp"
android:layout_height="200dp" />
</LinearLayout>
<RelativeLayout
android:id="#+id/relative_layout"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/save_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSave"
android:text="Save" />
</RelativeLayout>
</FrameLayout>
Activity:
public class TestActivity extends AppCompatActivity {
private boolean isButtonShown = false;
ImageViewPager viewPager;
RelativeLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
viewPager = findViewById(R.id.viewpager);
layout = findViewById(R.id.relative_layout);
}
public void onPagerClick(View view) {
if (isButtonShown) {
isButtonShown = false;
layout.setVisibility(View.GONE);
} else {
isButtonShown = true;
layout.setVisibility(View.VISIBLE);
}
}
}
Try this type code for visiablity ..
private void share(){
relativeLayout.setVisibility(View.VISIBLE);
linearLayoutViewpager.setVisibility(View.GONE);
}
linearLayoutViewpager=findViewById(R.id.linearLayoutViewpager);
linearLayoutViewpager.setVisibility(View.VISIBLE);
relativeLayout=findViewById(R.id.relativelayoutforbuttons);
relativeLayout.setVisibility(View.GONE);
it only sample code but mange according your needs.
final boolean flag=true;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (flag){
relativeLayout.setVisibility(View.VISIBLE);
flag=false;
}
else{
relativeLayout.setVisibility(View.GONE);
}
}
});
I have Recyclerview inside the nestedscrollview and I want to scroll the nestedscrollview to the buttom display loading and load more list to recyclerview.
Here is my xml.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="kh.com.iknow.endless.MainActivity">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Filter"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Sort"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:scrollbars="vertical" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
you can do it in two ways :
1- adding header to recyclerview
2- using setOnScrollChangeListener method of NestedScrolview
I prefer the second way :
NestedScrollView nestedSV = (NestedScrollView) findViewById(R.id.nested_sync_scrollview);
if (nestedSV != null) {
nestedSV.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
#Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
String TAG = "nested_sync";
if (scrollY > oldScrollY) {
Log.i(TAG, "Scroll DOWN");
}
if (scrollY < oldScrollY) {
Log.i(TAG, "Scroll UP");
}
if (scrollY == 0) {
Log.i(TAG, "TOP SCROLL");
}
if (scrollY == (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
Log.i(TAG, "BOTTOM SCROLL");
if (!isRecyclerViewWaitingtoLaadData) //check for scroll down
{
if (!loadedAllItems) {
showUnSentData();
}
}
}
}
});
}
<?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:background="#color/off_white_bg"
android:orientation="vertical">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="2dp"
android:fitsSystemWindows="true">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollViewId"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical"
app:layout_scrollFlags="scroll|enterAlways">
<LinearLayout
android:id="#+id/permiumLAyout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/divider"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:focusableInTouchMode="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="visible">
<!-- List view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/btn_br_color"
android:padding="3dp">
<TextView
android:id="#+id/primiumGameNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill"
android:layout_marginLeft="15dp"
android:gravity="center"
android:maxLines="4"
android:text="Primium Games"
android:textAppearance="#style/TextAppearance.AppCompat.Body1"
android:textColor="#color/row_text_color"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_primiumGameList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:isScrollContainer="false"
android:nestedScrollingEnabled="false"
android:paddingBottom="3dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="3dp" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</FrameLayout>
</LinearLayout>
I Noted one issue putting my RecyclerView inside the NestedScrollView. I realized that scrolling the content of my RecyclerView slacked.Getting issue in scrolling. And one main issue load more data getting issue for load data inside NestedScrollView.
Solution: use load more event like this
mRecAdapter = new RecyclerAdapter(recylerView,
primiumgameDetailsArrayList, getActivity(), cost);
recylerView.setAdapter(mRecAdapter);
//set load more listener for the RecyclerView adapter
mRecAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
#Override
public void onLoadMore () {
**mRecyclerView.setNestedScrollingEnabled(false);**
if (reqCountStatus.equalsIgnoreCase("true")) {
primiumgameDetailsArrayList.add(null);
mRecAdapter.notifyItemInserted(primiumgameDetailsArrayList.size() - 1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
primiumgameDetailsArrayList.remove(primiumgameDetailsArrayList.size() - 1);
mRecAdapter.notifyItemRemoved(primiumgameDetailsArrayList.size());
int index = primiumgameDetailsArrayList.size();
primiumGameloadData(mRecyclerView, index);
}
}, 5000);
} else {
mRecyclerView.setNestedScrollingEnabled(false);
Toast.makeText(getActivity().getApplicationContext(),
"Loading data completed", Toast.LENGTH_SHORT).show();
}
}
});
Note:I had to disable the scroll functionality of my RecyclerView with this method mRecyclerView.setNestedScrollingEnabled(false); and enable when load more request for data mRecyclerView.setNestedScrollingEnabled(true)
I have a weird "problem" or may be it's a "feature" and I just don't know, whenever a NativeAdExpress is loaded in my RecyclerView if only part of the NativeAd is visible, it forces the RecyclerView to scroll until the Native ad becomes fully visible, this behavior causes the list to keep jumping as I scroll.
My Layout is mainly:
Activity > AppBar with Tabs and ViewPager > each Page in the Pager contains PullToRefresh and inside it there's a RecyclerView,
The RecyclerView has 2 types of items (Article and NativeAdExpress).
UPDATE: My guess on why this is happening is mainly because native ads express render in a webview, and this webview receives focus then this causes the RecyclerView to scroll to it, but that's only a Guess
UPDATE 2: Apparently this is an issue in Support Lib. 24.0.0, that's the cost of being too up2date :(
Heres's my Full XML/Layouts
<?xml version="1.0" encoding="utf-8"?>
<my.package.custom.views.CustomDrawerLayout
android:id="#+id/drawer_layout"
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:fitsSystemWindows="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:openDrawer="end">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
style="#style/AlertDialog.AppCompat.Light"
fontPath="fonts/fonts/DroidKufi-Regular.ttf"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:fitsSystemWindows="true"
app:elevation="5px"
app:headerLayout="#layout/nav_header"
app:itemIconTint="#color/colorPrimary"
app:itemTextColor="#color/contentColor"
app:actionLayout="#layout/nav_item_layout"
app:menu="#menu/drawer_menu"
app:theme="#style/NavDrawerStyle"
tools:openDrawer="end"
/>
</my.package.custom.views.CustomDrawerLayout>
where "app_bar_main.xml" is as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true"
tools:context=".ui.activities.ArticlesListActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="52dp"
android:background="?attr/colorPrimary"
android:gravity="end"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingEnd="14dp"
android:paddingStart="14dp">
<android.support.v7.widget.AppCompatImageButton
android:id="#+id/ivCustomDrawable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="#color/transparent"
android:tint="#color/white"
/>
<TextView
android:id="#+id/view_title"
android:visibility="gone"
style="#style/SectionTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<android.support.v7.widget.AppCompatSpinner
android:id="#+id/sources_spinner"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:transitionName="#string/transition_splash_logo"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
tools:targetApi="lollipop"/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
style="#style/TabsStyle"
android:layout_width="match_parent"
android:layout_height="42dp"
android:layout_gravity="bottom"
android:layout_marginTop="0dp"
android:transitionGroup="true"
app:tabContentStart="0dp"
app:tabGravity="fill"
app:tabIndicatorColor="#color/white"
app:tabIndicatorHeight="3dp"
app:tabMode="scrollable"
app:tabPaddingBottom="0dp"
app:tabPaddingTop="0dp"
app:tabTextAppearance="#style/TextAppearance.RegularTextFont"
/>
</android.support.design.widget.AppBarLayout>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".ui.activities.ArticlesListActivity"
tools:showIn="#layout/activity_newsitem_list">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
and finally I have 2 View Types Item and NativeAdExpress:
The NativeAdExpress ViewHolder is as follows:
public class NativeExpressAdViewHolder extends BaseCardAdViewHolder {
private final NativeExpressAdView view;
private boolean loaded = false;
private AdListener adListener;
private WeakReference<Context> context;
public NativeExpressAdViewHolder(View itemView, String adId, Context context) {
super(itemView);
view = new NativeExpressAdView(context);
view.setAdUnitId(adId);
((LinearLayout) itemView.findViewById(R.id.express_ad_holder)).addView(view);
this.context = new WeakReference<>(context);
}
public void loadAd(float cardWidthInDips) {
if (!loaded && null != context.get() && !view.isLoading()) {
int width = cardWidthInDips > 0 ? (int) cardWidthInDips : 330;
if (view.getAdSize() == null) {
view.setAdSize(new AdSize(width, 330));
view.setAdListener(new AdListener() {
#Override
public void onAdLoaded() {
super.onAdLoaded();
loaded = true;
if (adListener != null) {
adListener.onAdLoaded();
}
}
#Override
public void onAdFailedToLoad(int i) {
super.onAdFailedToLoad(i);
if (adListener != null) {
adListener.onAdFailedToLoad(i);
}
}
#Override
public void onAdOpened() {
super.onAdOpened();
if (adListener != null) {
adListener.onAdOpened();
}
}
});
}
new Handler(context.get().getMainLooper()).post(new Runnable() {
#Override
public void run() {
view.loadAd(new AdRequest.Builder().build());
}
});
}
}
public NativeExpressAdView getView() {
return view;
}
public void setAdListener(AdListener adListener) {
this.adListener = adListener;
}
#Override
public void destroyAd() {
if (view != null) {
view.destroy();
loaded = false;
}
}
}
and ads are create using a custom adapter as follows:
private BaseCardViewHolder createNativeExpressAdViewHolder(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ad_express, parent, false);
final NativeExpressAdViewHolder viewHolder = new NativeExpressAdViewHolder(
view,
adManager.getNativeExpressAdId(),
context.get()
);
adViewHolders.add(viewHolder);
viewHolder.setAdListener(new AdListener() {
#Override
public void onAdFailedToLoad(int errorCode) {
Log.i("ADS", "onAdFailedToLoad " + errorCode);
}
#Override
public void onAdLoaded() {
super.onAdLoaded();
// Do something
}
});
viewHolder.loadAd(cardWidthInDips);
return viewHolder;
}
I did not understand where you actually implement a RecyclerView in your code but here is anyway maybe something that could work in your case.
I had a similar problem with a GridView always getting the focus during a Fragment first load, it was also automatically scrolling down straight to the GridView.
After a lot of tests, I finally stopped this behavior with this one line on the parent layout of the GridView:
android:descendantFocusability="blocksDescendants"
This line basically means that all descendants from the parent layout will not get focus anymore. You can try it out on your RecyclerView parent layout.
I don't know if it's an issue, but the it looks like RecyclerView changed its behavior somewhere from support library 23.4.0 to 24.2.0.
Now instead of defaulting to descendantFocusability = beforeDescendants, it defaults to afterDescendants, which causes it to offer the focus to their children instead of taking it for itself.
When a child takes the focus, it ends up scrolling to make it visible.
I fixed it by adding android:descendantFocusability="beforeDescendants" to the RecyclerView, to recover the previous behavior, where it keeps the focus itself.
I had a similar issue with RecyclerView scrolling, not specifically to NativeAdExpress...but there seems to be an issue with the Android Support library 24.0.0 related to this. The android:descendantFocusability="blocksDescendants" didn't work for me. But downgrading to Android Support library 23.4.0 made it start working again.
I've implemented a swipe refresh layout onto one of my List Views however the view is not sliding down when I swipe and the icon is not visible. Even though it seems it doesn't work, it does actually fire off the OnRefresh listener.
Also I think its worth mentioning that I'm using the ListView on a fragment so i'm initializing the listener in the fragment activity which is displayed below.
Swipe Refresh XML
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"
android:layout_gravity="center_horizontal"
android:dividerHeight="1sp"
android:translationZ="5dp"
android:background="#color/background_gray"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:clickable="true"
/>
</android.support.v4.widget.SwipeRefreshLayout>
Fragment Activity
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) getActivity().findViewById(R.id.swipe_refresh_layout);
ListView lView = (ListView) getActivity().findViewById(R.id.listView);
mSwipeRefreshLayout.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);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(true);
((MainActivity) getActivity()).refresh();
new Handler().postDelayed(new Runnable() {
#Override public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
}, 5000);
}
});
lView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
#Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0)
mSwipeRefreshLayout.setEnabled(true);
else
mSwipeRefreshLayout.setEnabled(false);
}
});
}
I solved it, it appears that this is a current bug with the SwipeRefreshLayout. It will only work when Listview is wrapped inside a FrameLayout.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"
android:layout_gravity="center_horizontal"
android:dividerHeight="1sp"
android:translationZ="5dp"
android:background="#color/background_gray"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:clickable="true"
/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Simply set the property [android:clickable="true"] for the Immediate clild layout of SwipeRefreshLayout which occupies complete screen area.i.e. whose width and height is match_parent.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/srlayout_Container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
<RelativeLayout
android:id="#+id/rl_MainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
<!-- Placeholder for Other View or ViewGroup as Clild -->
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>