How to put icon in SlidingTab? - java

How i can put icon in my tab using SlidingTabLayout. I just want to change the Titles into Icon. Please help me on how to do it.
Here is the code
ViewPagerAdapter.java
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
//This method return the fragment for the every position in the View Pager
#Override
public Fragment getItem(int position) {
if(position == 0) // if the position is 0 we are returning the First tab
{
OrderTab ordertab = new OrderTab();
return ordertab;
}
else if(position==1) // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
{
ViewOrderTab viewordertab = new ViewOrderTab();
return viewordertab;
}
else
{
OrderStatus orderstatus = new OrderStatus();
return orderstatus;
}
}
// This method return the titles for the Tabs in the Tab Strip
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
// This method return the Number of tabs for the tabs Strip
#Override
public int getCount() {
return NumbOfTabs;
}
public static interface FirstShot
{
public void onFirstShot();
}
}
SlidingTabLayout.java
package com.example.work.mcoatorderingapp;
import android.content.Context;
import android.graphics.Typeface;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* To be used with ViewPager to provide a tab indicator component which give constant feedback as to
* the user's scroll progress.
* <p>
* To use the component, simply add it to your view hierarchy. Then in your
* {#link android.app.Activity} or {#link android.support.v4.app.Fragment} call
* {#link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
* <p>
* The colors can be customized in two ways. The first and simplest is to provide an array of colors
* via {#link #setSelectedIndicatorColors(int...)}. The
* alternative is via the {#link TabColorizer} interface which provides you complete control over
* which color is used for any individual position.
* <p>
* The views used as tabs can be customized by calling {#link #setCustomTabView(int, int)},
* providing the layout ID of your custom layout.
*/
public class SlidingTabLayout extends HorizontalScrollView {
/**
* Allows complete control over the colors drawn in the tab layout. Set with
* {#link #setCustomTabColorizer(TabColorizer)}.
*/
public interface TabColorizer {
/**
* #return return the color of the indicator used when {#code position} is selected.
*/
int getIndicatorColor(int position);
}
private static final int TITLE_OFFSET_DIPS = 24;
private static final int TAB_VIEW_PADDING_DIPS = 16;
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
private int mTitleOffset;
private int mTabViewLayoutId;
private int mTabViewTextViewId;
private boolean mDistributeEvenly;
private ViewPager mViewPager;
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
private final SlidingTabStrip mTabStrip;
public SlidingTabLayout(Context context) {
this(context, null);
}
public SlidingTabLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// Disable the Scroll Bar
setHorizontalScrollBarEnabled(false);
// Make sure that the Tab Strips fills this View
setFillViewport(true);
mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
mTabStrip = new SlidingTabStrip(context);
addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
}
/**
* Set the custom {#link TabColorizer} to be used.
*
* If you only require simple custmisation then you can use
* {#link #setSelectedIndicatorColors(int...)} to achieve
* similar effects.
*/
public void setCustomTabColorizer(TabColorizer tabColorizer) {
mTabStrip.setCustomTabColorizer(tabColorizer);
}
public void setDistributeEvenly(boolean distributeEvenly) {
mDistributeEvenly = distributeEvenly;
}
/**
* Sets the colors to be used for indicating the selected tab. These colors are treated as a
* circular array. Providing one color will mean that all tabs are indicated with the same color.
*/
public void setSelectedIndicatorColors(int... colors) {
mTabStrip.setSelectedIndicatorColors(colors);
}
/**
* Set the {#link ViewPager.OnPageChangeListener}. When using {#link SlidingTabLayout} you are
* required to set any {#link ViewPager.OnPageChangeListener} through this method. This is so
* that the layout can update it's scroll position correctly.
*
* #see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
*/
public void OnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mViewPagerPageChangeListener = listener;
}
/**
* Set the custom layout to be inflated for the tab views.
*
* #param layoutResId Layout id to be inflated
* #param textViewId id of the {#link TextView} in the inflated view
*/
public void setCustomTabView(int layoutResId, int textViewId) {
mTabViewLayoutId = layoutResId;
mTabViewTextViewId = textViewId;
}
/**
* Sets the associated view pager. Note that the assumption here is that the pager content
* (number of tabs and tab titles) does not change after this call has been made.
*/
public void setViewPager(ViewPager viewPager) {
mTabStrip.removeAllViews();
mViewPager = viewPager;
if (viewPager != null) {
viewPager.setOnPageChangeListener(new InternalViewPagerListener());
populateTabStrip();
}
}
/**
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
* {#link #setCustomTabView(int, int)}.
*/
protected TextView createDefaultTabView(Context context) {
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
outValue, true);
textView.setBackgroundResource(outValue.resourceId);
textView.setAllCaps(true);
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);
return textView;
}
private void populateTabStrip() {
final PagerAdapter adapter = mViewPager.getAdapter();
final View.OnClickListener tabClickListener = new TabClickListener();
for (int i = 0; i < adapter.getCount(); i++) {
View tabView = null;
TextView tabTitleView = null;
if (mTabViewLayoutId != 0) {
// If there is a custom tab view layout id set, try and inflate it
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
false);
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
}
if (tabView == null) {
tabView = createDefaultTabView(getContext());
}
if (tabTitleView == null && TextView.class.isInstance(tabView)) {
tabTitleView = (TextView) tabView;
}
if (mDistributeEvenly) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = 1;
}
tabTitleView.setText(adapter.getPageTitle(i));
tabView.setOnClickListener(tabClickListener);
String desc = mContentDescriptions.get(i, null);
if (desc != null) {
tabView.setContentDescription(desc);
}
mTabStrip.addView(tabView);
if (i == mViewPager.getCurrentItem()) {
tabView.setSelected(true);
}
tabTitleView.setTextColor(getResources().getColorStateList(R.color.selector));
tabTitleView.setTextSize(14);
}
}
public void setContentDescription(int i, String desc) {
mContentDescriptions.put(i, desc);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mViewPager != null) {
scrollToTab(mViewPager.getCurrentItem(), 0);
}
}
private void scrollToTab(int tabIndex, int positionOffset) {
final int tabStripChildCount = mTabStrip.getChildCount();
if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
return;
}
View selectedChild = mTabStrip.getChildAt(tabIndex);
if (selectedChild != null) {
int targetScrollX = selectedChild.getLeft() + positionOffset;
if (tabIndex > 0 || positionOffset > 0) {
// If we're not at the first child and are mid-scroll, make sure we obey the offset
targetScrollX -= mTitleOffset;
}
scrollTo(targetScrollX, 0);
}
}
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
private int mScrollState;
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
int tabStripChildCount = mTabStrip.getChildCount();
if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
return;
}
mTabStrip.onViewPagerPageChanged(position, positionOffset);
View selectedTitle = mTabStrip.getChildAt(position);
int extraOffset = (selectedTitle != null)
? (int) (positionOffset * selectedTitle.getWidth())
: 0;
scrollToTab(position, extraOffset);
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mTabStrip.onViewPagerPageChanged(position, 0f);
scrollToTab(position, 0);
}
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
mTabStrip.getChildAt(i).setSelected(position == i);
}
if (mViewPagerPageChangeListener != null) {
mViewPagerPageChangeListener.onPageSelected(position);
}
}
}
private class TabClickListener implements View.OnClickListener {
#Override
public void onClick(View v) {
for (int i = 0; i < mTabStrip.getChildCount(); i++) {
if (v == mTabStrip.getChildAt(i)) {
mViewPager.setCurrentItem(i);
return;
}
}
}
}
}
The Fragments are OrderTab.java the same code with ViewOrderTab.java and OrderStatus.java
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class OrderStatus extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.orderstatus_list,container,false);
return v;
}
}
MainActivity.java
EditText search;
ProgressDialog pDialog;
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[] = {"Order Product", "Cart", "Order Status"};
int Numboftabs = 3;
String titlebar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs=(SlidingTabLayout)
findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer()
{
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
}
);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);

Try
private int[] imageResId = {
R.drawable.ic_home,
R.drawable.ic_my_timeline,
R.drawable.ic_my_pages,
R.drawable.ic_my_groups,
R.drawable.ic_liked_pages
};
#Override
public CharSequence getPageTitle(int position) {
Drawable image = mContext.getResources().getDrawable(imageResId[position]);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
SpannableString sb = new SpannableString(" ");
ImageSpan imageSpan = new ImageSpan(image, ImageSpan.ALIGN_BOTTOM);
sb.setSpan(imageSpan, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return sb;
}
instead of
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
in your ViewPagerAdapter class.
EDIT1:
In your activity change
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
to
adapter = new ViewPagerAdapter(this, getSupportFragmentManager(), Titles, Numboftabs);
Then in your ViewPagerAdapter following changes are needed.
Context mContext;
public ViewPagerAdapter(Context context, FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.mContext = context;
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
EDIT2:
try extending FragmentPagerAdapter instead of FragmentStatePagerAdapter in your ViewPagerAdapter.
In your main activity code should be this:
tabs=(SlidingTabLayout)findViewById(R.id.tabs);
tabs.setCustomTabView(R.layout.custom_tab, 0);
Here is custom_tab.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textStyle="bold"
android:background="?android:selectableItemBackground"
android:padding="16dp"
android:gravity="center" />
hope this helps!

Related

How to update listview during search

This is my app when I start it:
When I click one of the item in the list view it will open a new activity and display some data.
When I search for something it looks like this:
And when I click an item in the list it starts a new activity. But the activity it starts is not accurate.
Here's my code:
HomeActivity.class
package com.thesis.herbalmedicines.activity;
import java.util.ArrayList;
import java.util.Arrays;
import android.app.Activity;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
public class HomeActivity extends BaseActivity implements
SearchView.OnQueryTextListener {
ListView lv;
SearchView search;
String[] herb_names, sample_arr; //= ["Boils","",""];//, iso_codes;
TypedArray herb_pics;
ArrayList<Home> homelist;
HomeAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.home_layout, frameLayout);
mDrawerList.setItemChecked(position, true);
setTitle(listArray[position]);
android.app.ActionBar ab = getActionBar();
ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#50B222"));
ab.setBackgroundDrawable(colorDrawable);
lv = (ListView) findViewById(R.id.list_view);
search = (SearchView) findViewById(R.id.search_view);
herb_names = getResources().getStringArray(R.array.herb_names);
//iso_codes = getResources().getStringArray(R.array.iso_Code);
herb_pics = getResources().obtainTypedArray(R.array.herb_pics);
homelist = new ArrayList<Home>();
for (int i = 0; i < herb_names.length; i++) {
Home home = new Home(herb_names[i], //iso_codes[i],
herb_pics.getResourceId(i, -1));
homelist.add(home);
}
adapter = new HomeAdapter(getApplicationContext(), homelist);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position == 0) {
Intent a = new Intent(HomeActivity.this, Boils.class);
startActivity(a);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 1) {
Intent b = new Intent(HomeActivity.this, Cystitis.class);
startActivity(b);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 2) {
Intent c = new Intent(HomeActivity.this, Asthma.class);
startActivity(c);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 3) {
Intent d = new Intent(HomeActivity.this, Feet.class);
startActivity(d);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
}
});
search.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
}
Home.java
package com.thesis.herbalmedicines.activity;
public class Home {
String name;
int pics;
Home(String name, int pics) {
this.name = name;
this.pics = pics;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPics() {
return pics;
}
public void setPics(int pics) {
this.pics = pics;
}
}
HomeAdapter.java
package com.thesis.herbalmedicines.activity;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
public class HomeAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Home> homelist;
ArrayList<Home> mStringFilterList;
ValueFilter valueFilter;
HomeAdapter(Context context, ArrayList<Home> homelist) {
this.context = context;
this.homelist = homelist;
mStringFilterList = homelist;
}
#Override
public int getCount() {
return homelist.size();
}
#Override
public Object getItem(int position) {
return homelist.get(position);
}
#Override
public long getItemId(int position) {
return homelist.indexOf(getItem(position));
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
TextView name_tv = (TextView) convertView.findViewById(R.id.name);
ImageView iv = (ImageView) convertView.findViewById(R.id.pic);
Home home = homelist.get(position);
name_tv.setText(home.getName());
iv.setImageResource(home.getPics());
}
return convertView;
}
#Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Home> filterList = new ArrayList<Home>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ((mStringFilterList.get(i).getName().toUpperCase())
.contains(constraint.toString().toUpperCase())) {
Home home = new Home(mStringFilterList.get(i)
.getName(), mStringFilterList.get(i)
.getPics());
filterList.add(home);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
homelist = (ArrayList<Home>) results.values;
notifyDataSetChanged();
}
}
}
Add a field that holds the class to be loaded inside the Home class. (The id field is optional)
public class Home {
int id;
String name;
int pics;
Class clazz;
Home(int id, String name, int pics, Class clazz) {
this.id = id;
this.name = name;
this.pics = pics;
this.clazz = clazz;
}
// getters and setters
}
During initialization of the homelist add the id,
// the classed to load
Class[] classes = {
Boils.class,
Cystitis.class,
Asthma.class,
Feet.class
};
for (int i = 0; i < herb_names.length; i++) {
Home home = new Home(i, herb_names[i], herb_pics.getResourceId(i, -1), classes[i]);
homelist.add(home);
}
Inside the setOnItemClickListener,
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Home item = (Home) adapter.getItem(position);
Intent d = new Intent(HomeActivity.this, item.getClazz());
startActivity(d);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
});
Couple of changes should be made in your adapter as well.
Inside the getView you are forcing the convertView to null. It is bad for performance. (Consider using a ViewHolder too)
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
}
TextView name_tv = (TextView) convertView.findViewById(R.id.name);
ImageView iv = (ImageView) convertView.findViewById(R.id.pic);
Home home = homelist.get(position);
name_tv.setText(home.getName());
iv.setImageResource(home.getPics());
return convertView;
}
Inside publishResults you are creating a new reference for the dataset. You should update the existing dataset.
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
homelist.clear();
homelist.addAll((ArrayList<Home>) results.values);
notifyDataSetChanged();
}
Set adpter to listview on every onSerch
Why do you use position to navigate to different activity ?
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position == 0) {
Intent a = new Intent(HomeActivity.this, Boils.class);
startActivity(a);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 1) {
Intent b = new Intent(HomeActivity.this, Cystitis.class);
startActivity(b);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 2) {
Intent c = new Intent(HomeActivity.this, Asthma.class);
startActivity(c);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
else if (position == 3) {
Intent d = new Intent(HomeActivity.this, Feet.class);
startActivity(d);
/** Fading Transition Effect */
HomeActivity.this.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
}
});
search.setOnQueryTextListener(this);
}
This will always reset your position whenever you adapter refresh from search result.
To do this in better way. Just create custom listener like following in your adapter.
Public interface ListViewClick{
void onListClick(Object type)
}
Register your receiver in activity and pass type of activity to launch from adapter
private ListViewClick callback;
HomeAdapter(Context context, ArrayList<Home> homelist,ListViewClick callback) {
this.context = context;
this.homelist = homelist;
mStringFilterList = homelist;
this.callback = callback;
}
and on click listener of convertView pass callback.onListClick(//type of activity to launch).
Just keep reference of 'type of activity to launch in Home enitity'. so you can recognize which activity is ti be launch when clicking on particular row of list view.

Disable left swipe on cardview

I am using SwipeableRecyclerView and I was wondering how I can disable left swipe?
This is my code:
MainActivity.class
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends ActionBarActivity {
private CardViewAdapter mAdapter;
private ArrayList<String> mItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mItems = new ArrayList<>(30);
for (int i = 0; i < 30; i++) {
mItems.add(String.format("Card number %02d", i));
}
OnItemTouchListener itemTouchListener = new OnItemTouchListener() {
#Override
public void onCardViewTap(View view, int position) {
Toast.makeText(MainActivity.this, "Tapped " + mItems.get(position), Toast.LENGTH_SHORT).show();
}
#Override
public void onButton1Click(View view, int position) {
Toast.makeText(MainActivity.this, "Clicked Button1 in " + mItems.get(position), Toast.LENGTH_SHORT).show();
}
#Override
public void onButton2Click(View view, int position) {
Toast.makeText(MainActivity.this, "Clicked Button2 in " + mItems.get(position), Toast.LENGTH_SHORT).show();
}
};
mAdapter = new CardViewAdapter(mItems, itemTouchListener);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mAdapter);
SwipeableRecyclerViewTouchListener swipeTouchListener =
new SwipeableRecyclerViewTouchListener(recyclerView,
new SwipeableRecyclerViewTouchListener.SwipeListener() {
#Override
public boolean canSwipe(int position) {
return true;
}
#Override
public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
// Toast.makeText(MainActivity.this, mItems.get(position) + " swiped left", Toast.LENGTH_SHORT).show();
mItems.remove(position);
mAdapter.notifyItemRemoved(position);
}
mAdapter.notifyDataSetChanged();
}
#Override
public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) {
for (int position : reverseSortedPositions) {
// Toast.makeText(MainActivity.this, mItems.get(position) + " swiped right", Toast.LENGTH_SHORT).show();
mItems.remove(position);
mAdapter.notifyItemRemoved(position);
}
mAdapter.notifyDataSetChanged();
}
});
recyclerView.addOnItemTouchListener(swipeTouchListener);
}
/**
* Interface for the touch events in each item
*/
public interface OnItemTouchListener {
/**
* Callback invoked when the user Taps one of the RecyclerView items
*
* #param view the CardView touched
* #param position the index of the item touched in the RecyclerView
*/
public void onCardViewTap(View view, int position);
/**
* Callback invoked when the Button1 of an item is touched
*
* #param view the Button touched
* #param position the index of the item touched in the RecyclerView
*/
public void onButton1Click(View view, int position);
/**
* Callback invoked when the Button2 of an item is touched
*
* #param view the Button touched
* #param position the index of the item touched in the RecyclerView
*/
public void onButton2Click(View view, int position);
}
/**
* A simple adapter that loads a CardView layout with one TextView and two Buttons, and
* listens to clicks on the Buttons or on the CardView
*/
public class CardViewAdapter extends RecyclerView.Adapter<CardViewAdapter.ViewHolder> {
private List<String> cards;
private OnItemTouchListener onItemTouchListener;
public CardViewAdapter(List<String> cards, OnItemTouchListener onItemTouchListener) {
this.cards = cards;
this.onItemTouchListener = onItemTouchListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_view_layout, viewGroup, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.title.setText(cards.get(i));
}
#Override
public int getItemCount() {
return cards == null ? 0 : cards.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private Button button1;
private Button button2;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.card_view_title);
button1 = (Button) itemView.findViewById(R.id.card_view_button1);
button2 = (Button) itemView.findViewById(R.id.card_view_button2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemTouchListener.onButton1Click(v, getPosition());
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemTouchListener.onButton2Click(v, getPosition());
}
});
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemTouchListener.onCardViewTap(v, getPosition());
}
});
}
}
}
}
SwipeableRecyclerViewTouchListener.class
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A {#link View.OnTouchListener} that makes the list items in a {#link android.support.v7.widget.RecyclerView}
* dismissable by swiping.
* <p/>
* <p>Example usage:</p>
* <p/>
* <pre>
* SwipeDismissRecyclerViewTouchListener touchListener =
* new SwipeDismissRecyclerViewTouchListener(
* listView,
* new SwipeDismissRecyclerViewTouchListener.OnDismissCallback() {
* public void onDismiss(ListView listView, int[] reverseSortedPositions) {
* for (int position : reverseSortedPositions) {
* adapter.remove(adapter.getItem(position));
* }
* adapter.notifyDataSetChanged();
* }
* });
* listView.setOnTouchListener(touchListener);
* listView.setOnScrollListener(touchListener.makeScrollListener());
* </pre>
* <p/>
* <p>This class Requires API level 12 or later due to use of {#link
* android.view.ViewPropertyAnimator}.</p>
*/
public class SwipeableRecyclerViewTouchListener implements RecyclerView.OnItemTouchListener {
// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
private int mMaxFlingVelocity;
private long mAnimationTime;
// Fixed properties
private RecyclerView mRecyclerView;
private SwipeListener mSwipeListener;
private int mViewWidth = 1; // 1 and not 0 to prevent dividing by zero
// Transient properties
private List<PendingDismissData> mPendingDismisses = new ArrayList<>();
private int mDismissAnimationRefCount = 0;
private float mAlpha;
private float mDownX;
private float mDownY;
private boolean mSwiping;
private int mSwipingSlop;
private VelocityTracker mVelocityTracker;
private int mDownPosition;
private int mAnimatingPosition = ListView.INVALID_POSITION;
private View mDownView;
private boolean mPaused;
private float mFinalDelta;
/**
* Constructs a new swipe touch listener for the given {#link android.support.v7.widget.RecyclerView}
*
* #param recyclerView The recycler view whose items should be dismissable by swiping.
* #param listener The listener for the swipe events.
*/
public SwipeableRecyclerViewTouchListener(RecyclerView recyclerView, SwipeListener listener) {
ViewConfiguration vc = ViewConfiguration.get(recyclerView.getContext());
mSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity() * 16;
mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
mAnimationTime = recyclerView.getContext().getResources().getInteger(
android.R.integer.config_shortAnimTime);
mRecyclerView = recyclerView;
mSwipeListener = listener;
/**
* This will ensure that this SwipeableRecyclerViewTouchListener is paused during list view scrolling.
* If a scroll listener is already assigned, the caller should still pass scroll changes through
* to this listener.
*/
mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
setEnabled(newState != RecyclerView.SCROLL_STATE_DRAGGING);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
}
});
}
/**
* Enables or disables (pauses or resumes) watching for swipe-to-dismiss gestures.
*
* #param enabled Whether or not to watch for gestures.
*/
public void setEnabled(boolean enabled) {
mPaused = !enabled;
}
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
return handleTouchEvent(motionEvent);
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent motionEvent) {
handleTouchEvent(motionEvent);
}
private boolean handleTouchEvent(MotionEvent motionEvent) {
if (mViewWidth < 2) {
mViewWidth = mRecyclerView.getWidth();
}
switch (motionEvent.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
if (mPaused) {
break;
}
// Find the child view that was touched (perform a hit test)
Rect rect = new Rect();
int childCount = mRecyclerView.getChildCount();
int[] listViewCoords = new int[2];
mRecyclerView.getLocationOnScreen(listViewCoords);
int x = (int) motionEvent.getRawX() - listViewCoords[0];
int y = (int) motionEvent.getRawY() - listViewCoords[1];
View child;
for (int i = 0; i < childCount; i++) {
child = mRecyclerView.getChildAt(i);
child.getHitRect(rect);
if (rect.contains(x, y)) {
mDownView = child;
break;
}
}
if (mDownView != null && mAnimatingPosition != mRecyclerView.getChildPosition(mDownView)) {
mAlpha = mDownView.getAlpha();
mDownX = motionEvent.getRawX();
mDownY = motionEvent.getRawY();
mDownPosition = mRecyclerView.getChildPosition(mDownView);
if (mSwipeListener.canSwipe(mDownPosition)) {
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(motionEvent);
} else {
mDownView = null;
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
if (mVelocityTracker == null) {
break;
}
if (mDownView != null && mSwiping) {
// cancel
mDownView.animate()
.translationX(0)
.alpha(mAlpha)
.setDuration(mAnimationTime)
.setListener(null);
}
mVelocityTracker.recycle();
mVelocityTracker = null;
mDownX = 0;
mDownY = 0;
mDownView = null;
mDownPosition = ListView.INVALID_POSITION;
mSwiping = false;
break;
}
case MotionEvent.ACTION_UP: {
if (mVelocityTracker == null) {
break;
}
mFinalDelta = motionEvent.getRawX() - mDownX;
mVelocityTracker.addMovement(motionEvent);
mVelocityTracker.computeCurrentVelocity(1000);
float velocityX = mVelocityTracker.getXVelocity();
float absVelocityX = Math.abs(velocityX);
float absVelocityY = Math.abs(mVelocityTracker.getYVelocity());
boolean dismiss = false;
boolean dismissRight = false;
if (Math.abs(mFinalDelta) > mViewWidth / 2 && mSwiping) {
dismiss = true;
dismissRight = mFinalDelta > 0;
} else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity
&& absVelocityY < absVelocityX && mSwiping) {
// dismiss only if flinging in the same direction as dragging
dismiss = (velocityX < 0) == (mFinalDelta < 0);
dismissRight = mVelocityTracker.getXVelocity() > 0;
}
if (dismiss && mDownPosition != mAnimatingPosition && mDownPosition != ListView.INVALID_POSITION) {
// dismiss
final View downView = mDownView; // mDownView gets null'd before animation ends
final int downPosition = mDownPosition;
++mDismissAnimationRefCount;
mAnimatingPosition = mDownPosition;
mDownView.animate()
.translationX(dismissRight ? mViewWidth : -mViewWidth)
.alpha(0)
.setDuration(mAnimationTime)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
performDismiss(downView, downPosition);
}
});
} else {
// cancel
mDownView.animate()
.translationX(0)
.alpha(mAlpha)
.setDuration(mAnimationTime)
.setListener(null);
}
mVelocityTracker.recycle();
mVelocityTracker = null;
mDownX = 0;
mDownY = 0;
mDownView = null;
mDownPosition = ListView.INVALID_POSITION;
mSwiping = false;
break;
}
case MotionEvent.ACTION_MOVE: {
if (mVelocityTracker == null || mPaused) {
break;
}
mVelocityTracker.addMovement(motionEvent);
float deltaX = motionEvent.getRawX() - mDownX;
float deltaY = motionEvent.getRawY() - mDownY;
if (!mSwiping && Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) {
mSwiping = true;
mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop);
}
if (mSwiping) {
mDownView.setTranslationX(deltaX - mSwipingSlop);
mDownView.setAlpha(Math.max(0f, Math.min(mAlpha,
mAlpha * (1f - Math.abs(deltaX) / mViewWidth))));
return true;
}
break;
}
}
return false;
}
private void performDismiss(final View dismissView, final int dismissPosition) {
// Animate the dismissed list item to zero-height and fire the dismiss callback when
// all dismissed list item animations have completed. This triggers layout on each animation
// frame; in the future we may want to do something smarter and more performant.
final ViewGroup.LayoutParams lp = dismissView.getLayoutParams();
final int originalLayoutParamsHeight = lp.height;
final int originalHeight = dismissView.getHeight();
ValueAnimator animator = ValueAnimator.ofInt(originalHeight, 1).setDuration(mAnimationTime);
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
--mDismissAnimationRefCount;
if (mDismissAnimationRefCount == 0) {
// No active animations, process all pending dismisses.
// Sort by descending position
Collections.sort(mPendingDismisses);
int[] dismissPositions = new int[mPendingDismisses.size()];
for (int i = mPendingDismisses.size() - 1; i >= 0; i--) {
dismissPositions[i] = mPendingDismisses.get(i).position;
}
if (mFinalDelta > 0) {
mSwipeListener.onDismissedBySwipeRight(mRecyclerView, dismissPositions);
} else {
mSwipeListener.onDismissedBySwipeLeft(mRecyclerView, dismissPositions);
}
// Reset mDownPosition to avoid MotionEvent.ACTION_UP trying to start a dismiss
// animation with a stale position
mDownPosition = ListView.INVALID_POSITION;
ViewGroup.LayoutParams lp;
for (PendingDismissData pendingDismiss : mPendingDismisses) {
// Reset view presentation
pendingDismiss.view.setAlpha(mAlpha);
pendingDismiss.view.setTranslationX(0);
lp = pendingDismiss.view.getLayoutParams();
lp.height = originalLayoutParamsHeight;
pendingDismiss.view.setLayoutParams(lp);
}
// Send a cancel event
long time = SystemClock.uptimeMillis();
MotionEvent cancelEvent = MotionEvent.obtain(time, time,
MotionEvent.ACTION_CANCEL, 0, 0, 0);
mRecyclerView.dispatchTouchEvent(cancelEvent);
mPendingDismisses.clear();
mAnimatingPosition = ListView.INVALID_POSITION;
}
}
});
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
lp.height = (Integer) valueAnimator.getAnimatedValue();
dismissView.setLayoutParams(lp);
}
});
mPendingDismisses.add(new PendingDismissData(dismissPosition, dismissView));
animator.start();
}
/**
* The callback interface used by {#link SwipeableRecyclerViewTouchListener} to inform its client
* about a swipe of one or more list item positions.
*/
public interface SwipeListener {
/**
* Called to determine whether the given position can be swiped.
*/
boolean canSwipe(int position);
/**
* Called when the item has been dismissed by swiping to the left.
*
* #param recyclerView The originating {#link android.support.v7.widget.RecyclerView}.
* #param reverseSortedPositions An array of positions to dismiss, sorted in descending
* order for convenience.
*/
void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions);
/**
* Called when the item has been dismissed by swiping to the right.
*
* #param recyclerView The originating {#link android.support.v7.widget.RecyclerView}.
* #param reverseSortedPositions An array of positions to dismiss, sorted in descending
* order for convenience.
*/
void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions);
}
class PendingDismissData implements Comparable<PendingDismissData> {
public int position;
public View view;
public PendingDismissData(int position, View view) {
this.position = position;
this.view = view;
}
#Override
public int compareTo(#NonNull PendingDismissData other) {
// Sort by descending position
return other.position - position;
}
}
}
Use simple recyclerView and then You can use ItemTouchHelper.Callback
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final YourAdapter mAdapter;
public SimpleItemTouchHelperCallback(YourAdapter adapter) {
mAdapter = adapter;
}
#Override
public boolean isLongPressDragEnabled() {
return true;
}
#Override
public boolean isItemViewSwipeEnabled() {
return true;
}
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
#Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
}
In YourAdapter class which is extending recyclerview adapter add these functions.
public void onItemMove(int oldPosition, int newPosition) {
notifyItemMoved(oldPosition,newPosition);
}
public void onItemDismiss(int adapterPosition) {
/// here you can delete from the array and notify for that specific position
}
ItemTouchHelper provides some flags which you can see here
#Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
If you want to disable Left to Right Swipe just remove ItemTouchHelper.START flag.
If you want to disable Right to Left Swipe just remove ItemTouchHelper.END flag.
You can pass 0 value instead of swipeFlags. Swipe will not work.
Same goes for dragFlags.
I have implemented this as well and it works like a charm ;) Happy Coding <3

Add timer and set size to viewpager

I have viewpager in my main activity and i need set timer to it to
automatically change slide .
I need set defult size and position to my image ( any resolution) for any screen to show one third of my top screen like this Preview.
Mainactivity.java
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Image slide show
ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
ImageAdapter adapter = new ImageAdapter(this);
viewPager.setAdapter(adapter);
// End Image slide show
}
ImageAdapter.java
package com.example.gallery;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class ImageAdapter extends PagerAdapter {
Context context;
private int[] GalImages = new int[] {
R.drawable.one,
R.drawable.two,
R.drawable.three
};
ImageAdapter(Context context){
this.context=context;
}
#Override
public int getCount() {
return GalImages.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((ImageView) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_medium);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setImageResource(GalImages[position]);
((ViewPager) container).addView(imageView, 0);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((ImageView) object);
}
}
For timer,
in the main activity add these after viewPager.setAdapter(adapter);
myPager.setCurrentItem(0);
pagerAdapter.setTimer(myPager,7);
in the pager adapter class
//gloabals
final Handler handler = new Handler();
public Timer swipeTimer ;
/**
* this function swipes pages left to right for every 7 seconds
* #param myPager its viewpager.
* #param time as second, for 7 second enter 7
*
*/
public void setTimer(final ViewPager myPager, int time){
final int size =objects.size();
final Runnable Update = new Runnable() {
int NUM_PAGES =size;
int currentPage = 0 ;
public void run() {
if (currentPage == NUM_PAGES ) {
currentPage = 0;
}
myPager.setCurrentItem(currentPage++, true);
}
};
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
or you can use this one
/**
* this function swipes pages left to right for every 7 seconds
* #param myPager
* #param time
* #param numPages we recommend that it should be as much as much objects.size()
* #param curPage we recommend that it should start from 0
*
*/
public void setTimer(final ViewPager myPager, int time, final int numPages, final int curPage){
final Runnable Update = new Runnable() {
int NUM_PAGES =numPages;
int currentPage = curPage ;
public void run() {
if (currentPage == NUM_PAGES ) {
currentPage = 0;
}
myPager.setCurrentItem(currentPage++, true);
}
};
swipeTimer = new Timer();
swipeTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
this is for stopping timer
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null);
swipeTimer.cancel();
}

Trying to set custom BaseAdapter to listview

I am trying to accomplish this: http://blog.uncommons.org/2011/05/09/embedding-admob-adverts-in-android-listviews/.
I am stuck at setting the custom BaseAdapter I simply don't know what to put in the BASEADAPTER variable below.
Here is my adapter
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
/**
* List adapter decorator that inserts adverts into the list.
* #author Daniel Dyer
*/
public class AdvertisingAdapter extends BaseAdapter
{
private static final String ADMOB_PUBLISHER_ID = "---------------";
private final Activity activity;
private final BaseAdapter delegate;
private int resource;
private ArrayList<String> objects;
public AdvertisingAdapter(Activity activity, int resource, BaseAdapter delegate,
ArrayList<String> stories) {
// TODO Auto-generated constructor stub
this.resource = resource;
this.activity = activity;
this.delegate = delegate;
this.objects = stories;
delegate.registerDataSetObserver(new DataSetObserver()
{
#Override
public void onChanged()
{
notifyDataSetChanged();
}
#Override
public void onInvalidated()
{
notifyDataSetInvalidated();
}
});
}
public int getCount()
{
return delegate.getCount() + 1;
}
public Object getItem(int i)
{
return delegate.getItem(i - 1);
}
public long getItemId(int i)
{
return delegate.getItemId(i - 1);
}
public View getView(int position, View convertView, ViewGroup parent)
{
if ((position % 10) == 0)
{
if (convertView instanceof AdView)
{
return convertView;
}
else
{
AdView adView = new AdView(activity, AdSize.BANNER, ADMOB_PUBLISHER_ID);
// Disable focus for sub-views of the AdView to avoid problems with
// trackpad navigation of the list.
for (int i = 0; i < adView.getChildCount(); i++)
{
adView.getChildAt(i).setFocusable(false);
}
adView.setFocusable(false);
// Default layout params have to be converted to ListView compatible
// params otherwise there will be a ClassCastException.
float density = activity.getResources().getDisplayMetrics().density;
int height = Math.round(AdSize.BANNER.getHeight() * density);
AbsListView.LayoutParams params
= new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
height);
adView.setLayoutParams(params);
adView.loadAd(new AdRequest());
return adView;
}
}
else
{
return delegate.getView(position - 1, convertView, parent);
}
}
#Override
public int getViewTypeCount()
{
return delegate.getViewTypeCount() + 1;
}
#Override
public int getItemViewType(int position)
{
return position == 0 ? delegate.getViewTypeCount()
: delegate.getItemViewType(position - 1);
}
#Override
public boolean areAllItemsEnabled()
{
return false;
}
#Override
public boolean isEnabled(int position)
{
return position != 0 && delegate.isEnabled(position - 1);
}
}
And in my main activity here is where I'm trying to set my custom base adapter. What should the BASEADAPTER parameter be?
mListView.setAdapter(new AdvertisingAdapter(this,
android.R.layout.simple_list_item_1, BASEADAPTER, stories));
Its depend what you trying to show or display in listview, normally application context and desire data is to be passed to BaseAdapter constructor. For details info read BaseAdapter and even check Android ListView detailed tutorial.

Android FragmentTabHost - Not fully baked yet?

I wanted to see if anyone has had success with customization of tabs using FragmentTabHost that comes with the new Android API level 17.
I was excited to be able to nest a tabHost within my ViewPager SherlockFragments, but I'm having trouble doing simple things like moving the tabs to the bottom or changing the layout of the tabs.
Has anyone seen a good example of using this functionality?
This is the only example I could find in the Android docs, and theres just about nothing that describes its use. It also seems to ignore whatever is defined in the layout for R.id.fragment1.
My question I suppose would be if anyone has come across a good tutorial re:FragmentTabHost
or if they have an idea about how to a) put the nested tabs at the bottom or b) change the layout of said tabs.
I've tried all the usual methods, but since it appears the XML layout file is overridden, I haven't had much luck.
private FragmentTabHost mTabHost;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setContentView(R.layout.fragment_tabs);
mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
FragmentStackSupport.CountingFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
LoaderCursorSupport.CursorLoaderListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
LoaderCustomSupport.AppListFragment.class, null);
mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
return mTabHost;
}
After doing some research, it appears there may be a glitch with initializing the FragmentTabHost in the support library. The user here on Google code has provided a suggestion to this:
FragmentTabHost.java
private void initFragmentTabHost(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
new int[] { android.R.attr.inflatedId }, 0, 0);
mContainerId = a.getResourceId(0, 0);
a.recycle();
super.setOnTabChangedListener(this);
// If owner hasn't made its own view hierarchy, then as a convenience
// we will construct a standard one here.
/***** HERE COMMENT CODE BECAUSE findViewById(android.R.id.tabs) EVERY TIME IS NULL WE HAVE OWN LAYOUT ******//
// if (findViewById(android.R.id.tabs) == null) {
// LinearLayout ll = new LinearLayout(context);
// ll.setOrientation(LinearLayout.VERTICAL);
// addView(ll, new FrameLayout.LayoutParams(
// ViewGroup.LayoutParams.FILL_PARENT,
// ViewGroup.LayoutParams.FILL_PARENT));
//
// TabWidget tw = new TabWidget(context);
// tw.setId(android.R.id.tabs);
// tw.setOrientation(TabWidget.HORIZONTAL);
// ll.addView(tw, new LinearLayout.LayoutParams(
// ViewGroup.LayoutParams.FILL_PARENT,
// ViewGroup.LayoutParams.WRAP_CONTENT, 0));
//
// FrameLayout fl = new FrameLayout(context);
// fl.setId(android.R.id.tabcontent);
// ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));
//
// mRealTabContent = fl = new FrameLayout(context);
// mRealTabContent.setId(mContainerId);
// ll.addView(fl, new LinearLayout.LayoutParams(
// LinearLayout.LayoutParams.FILL_PARENT, 0, 1));
// }
}
XML Layout for fragment:
<android.support.v4.app.FragmentTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TabWidget
android:id="#android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
I finally got to the bottom of this. There is an issue with FragmentTabHost.java which will always create a TabHost element for you, no matter what you define in XML and inflate beforehand.
As such, I commented out that part of code when writing my own version of FragmentTabHost.java.
Make sure to use your new version of this in your XML layout, <com.example.app.MyFragmentTabHost
And of course inflate it:
Fragment1.java:
mTabHost = (MyFragmentTabHost) view.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), android.R.id.tabcontent);
MyFragmentTabHost.java:
package com.example.app;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TabHost;
/**
* Special TabHost that allows the use of {#link Fragment} objects for
* its tab content. When placing this in a view hierarchy, after inflating
* the hierarchy you must call {#link #setup(Context, FragmentManager, int)}
* to complete the initialization of the tab host.
*
*/
public class MyFragmentTabHost extends TabHost
implements TabHost.OnTabChangeListener {
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private FrameLayout mRealTabContent;
private Context mContext;
private FragmentManager mFragmentManager;
private int mContainerId;
private TabHost.OnTabChangeListener mOnTabChangeListener;
private TabInfo mLastTab;
private boolean mAttached;
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
private Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
static class SavedState extends BaseSavedState {
String curTab;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
curTab = in.readString();
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(curTab);
}
#Override
public String toString() {
return "FragmentTabHost.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " curTab=" + curTab + "}";
}
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public MyFragmentTabHost(Context context) {
// Note that we call through to the version that takes an AttributeSet,
// because the simple Context construct can result in a broken object!
super(context, null);
initFragmentTabHost(context, null);
}
public MyFragmentTabHost(Context context, AttributeSet attrs) {
super(context, attrs);
initFragmentTabHost(context, attrs);
}
private void initFragmentTabHost(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
new int[] { android.R.attr.inflatedId }, 0, 0);
mContainerId = a.getResourceId(0, 0);
a.recycle();
super.setOnTabChangedListener(this);
/*** REMOVE THE REST OF THIS FUNCTION ***/
/*** findViewById(android.R.id.tabs) IS NULL EVERY TIME ***/
}
/**
* #deprecated Don't call the original TabHost setup, you must instead
* call {#link #setup(Context, FragmentManager)} or
* {#link #setup(Context, FragmentManager, int)}.
*/
#Override #Deprecated
public void setup() {
throw new IllegalStateException(
"Must call setup() that takes a Context and FragmentManager");
}
public void setup(Context context, FragmentManager manager) {
super.setup();
mContext = context;
mFragmentManager = manager;
ensureContent();
}
public void setup(Context context, FragmentManager manager, int containerId) {
super.setup();
mContext = context;
mFragmentManager = manager;
mContainerId = containerId;
ensureContent();
mRealTabContent.setId(containerId);
// We must have an ID to be able to save/restore our state. If
// the owner hasn't set one at this point, we will set it ourself.
if (getId() == View.NO_ID) {
setId(android.R.id.tabhost);
}
}
private void ensureContent() {
if (mRealTabContent == null) {
mRealTabContent = (FrameLayout)findViewById(mContainerId);
if (mRealTabContent == null) {
throw new IllegalStateException(
"No tab content FrameLayout found for id " + mContainerId);
}
}
}
#Override
public void setOnTabChangedListener(OnTabChangeListener l) {
mOnTabChangeListener = l;
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
if (mAttached) {
// If we are already attached to the window, then check to make
// sure this tab's fragment is inactive if it exists. This shouldn't
// normally happen.
info.fragment = mFragmentManager.findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached()) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.detach(info.fragment);
ft.commit();
}
}
mTabs.add(info);
addTab(tabSpec);
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
String currentTab = getCurrentTabTag();
// Go through all tabs and make sure their fragments match
// the correct state.
FragmentTransaction ft = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
if (tab.fragment != null && !tab.fragment.isDetached()) {
if (tab.tag.equals(currentTab)) {
// The fragment for this tab is already there and
// active, and it is what we really want to have
// as the current tab. Nothing to do.
mLastTab = tab;
} else {
// This fragment was restored in the active state,
// but is not the current tab. Deactivate it.
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
ft.detach(tab.fragment);
}
}
}
// We are now ready to go. Make sure we are switched to the
// correct tab.
mAttached = true;
ft = doTabChanged(currentTab, ft);
if (ft != null) {
ft.commit();
mFragmentManager.executePendingTransactions();
}
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAttached = false;
}
#Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.curTab = getCurrentTabTag();
return ss;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
setCurrentTabByTag(ss.curTab);
}
#Override
public void onTabChanged(String tabId) {
if (mAttached) {
FragmentTransaction ft = doTabChanged(tabId, null);
if (ft != null) {
ft.commit();
}
}
if (mOnTabChangeListener != null) {
mOnTabChangeListener.onTabChanged(tabId);
}
}
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
TabInfo newTab = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId)) {
newTab = tab;
}
}
if (newTab == null) {
throw new IllegalStateException("No tab known for tag " + tabId);
}
if (mLastTab != newTab) {
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.detach(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
ft.attach(newTab.fragment);
}
}
mLastTab = newTab;
}
return ft;
}
}
I think, it was a mistake to set method initFragmentTabHost() to constructor. At that time TabHost don't his children - it happens after. LinearLayout, for example, work with his children in onMeasure() method (grepcode). ViewGroup in constructor just init variables, and set mChildrenCount = 0 (grepcode).
All what I can did, it's only costumize FragmentTabHost:
<android.support.v4.app.FragmentTabHost xmlns:a="http://schemas.android.com/apk/res/android"
a:id="#android:id/tabhost"
style="#style/Widget.TabHost"
a:inflatedId="#+id/content" />
And costumize Tabs (have problems with tab heights, I solve them in code):
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
style="#style/Widget.Tab" >
<TextView
a:id="#android:id/title"
style="#style/Widget.TabTitle" />
</LinearLayout>
In code:
tabSpec = mTabHost.newTabSpec(tag).setIndicator(createTab(caption));
...
private View createTab(CharSequence title) {
final View v = View.inflate(getActivity(), LAYOUT_TAB, null);
((TextView) v.findViewById(android.R.id.title)).setText(title);
return v;
}
I think other customization with TabWidget we can do only with programmatically manipulating, like this:
final View tabs = (TabWidget) mTabHost.findViewById(android.R.id.tabs);
final ViewGroup parent = (ViewGroup) mTabHost.getChildAt(0);
parent.removeView(tabs);
parent.addView(tabs);
IMHO, this is not good.
as far as i tested jamisOn solution is good. It is important to not initialize MyFragmentTabHost with its constructor. At least if the class holding the MyFragmentTabHost is a fragment. I haven`t tested with a FragmentActivity...
I'd like to mention some more issues with FragmentTabHost. I'm using a ViewPager where each page (View) contains a FragmenTabHost and I had to overcome several problems:
1) FragmentTabHost assumes that it's the only FragmentTabHost in its parent FragmentManager (2nd argument to FragmentTabHost.setup()). This causes the rest of the problems...
2) the "tags" you provide when calling addTab() are passed straight through to the FragmentManager, so if you just use hardcoded tags for all your pages (a perfectly reasonable thing to do) your first page will create tab fragments while every other page will reuse those tabs. Yes, page 2 controls page 1...
Solution is to generate unique tag names. I appended the page number to the hardcoded strings:
public Object instantiateItem( ViewGroup container, int position )
{
...
tabHost.addTab( tabHost.newTabSpec( "tab1_" + position ) ...);
tabHost.addTab( tabHost.newTabSpec( "tab2_" + position ) ...);
tabHost.addTab( tabHost.newTabSpec( "tab3_" + position ) ...);
...
}
3) All tab fragments get placed in a container identified only by "view id" (the 3rd argument to FragmentTabHost.setup()). This means that when the FragmentManager resolves the viewId to a View, it always finds the first instance (from the first page). All your other pages are ignored.
Solution to this is to assign unique ids to your "tab content" views, for example:
public Object instantiateItem( ViewGroup container, int position )
{
View view = m_inflater.inflate(R.layout.page, null);
View tabContent = view.findViewById(R.id.realtabcontent);
tabContent.setId(m_nextViewId);
m_nextViewId++;
MyFragmentTabHost tabHost = (MyFragmentTabHost) view.findViewById(android.R.id.tabhost);
tabHost.setup(m_activity, m_activity.getSupportFragmentManager(), tabContent.getId());
...
}
4) It doesn't remove tab fragments when destroyed. While the ViewPager destroys unused Views as you swipe, the FragmentTabHosts contained within those views "leak" the tab fragments. When the ViewPager re-instantiates a previously seen page (using previously used tags), FragmentTabHost will notice that the fragments for those tabs already exist and simply reattach them. This blows up because the fragments point to views that have been destroyed by the ViewPager.
The solution is to remove fragments when FragmentTabHost is destroyed. You'll want to add this code to onDetachedFromWindow() in your local copy of FragmentTabHost.java
class MyFragmentTabHost
{
...
protected void onDetachedFromWindow()
{
super.onDetachedFromWindow();
mAttached = false;
boolean removeFragments = false;
if( mContext instanceof Activity )
{
Activity activity = (Activity)mContext;
removeFragments = !activity.isDestroyed();
}
if( removeFragments )
{
FragmentTransaction ft = null;
for (int i = 0; i < mTabs.size(); i++)
{
TabInfo tab = mTabs.get(i);
if (tab.fragment != null)
{
if (ft == null)
{
ft = mFragmentManager.beginTransaction();
}
ft.remove(tab.fragment);
}
}
if (ft != null)
{
ft.commit();
mFragmentManager.executePendingTransactions();
}
}
}
You could probably also work around these issues by using a FragmentPagerAdapter or FragmentStatePagerAdapter (makes Fragments) instead of a standard PagerAdapter (makes Views). Then you'd call FragmentTabHost.setup( ... fragment.getChildFragmentManager() ... ).

Categories