I want my Android application to work with different skins. So what I plan is changing all the images and fonts I used in the application for different skins.
What is the best way for this? How can i init all imageviews with proper image resources?
P.S : I want to change the skin at runtime and don't want to restart the app.
Thanks..
you can create a ThemeManager class where you can manage the themes
public class ThemeManager {
static ThemeManager tmanage;
int ThemeCode;
int topBarBackground, bottomBarBackground, buttonBackground, textColor;
ArrayList<ThemeWrapper> twrapper = new ArrayList<ThemeWrapper>();
public static ThemeManager getInstance() {
if (tmanage != null)
return tmanage;
else
tmanage = new ThemeManager();
return tmanage;
}
public void setThemeCode(int themeCode) {
ThemeCode = themeCode;
setBottomBarBackground(themeCode);
setTopBarBackground(themeCode);
setButtonBackground(themeCode);
setTextColor(themeCode);
}
#SuppressWarnings("deprecation")
public void setTheme(ArrayList<View> v) {
for (int i = 0; i < v.size(); i++) {
if (v.get(i) instanceof RelativeLayout) {
RelativeLayout layout = (RelativeLayout) v.get(i);
layout.setBackgroundColor(getTopBarBackground());
}
else if (v.get(i) instanceof Button) {
Button layout = (Button) v.get(i);
layout.setBackgroundDrawable(getShape(getButtonBackground()));
layout.setPadding(5, 5, 5, 5);
layout.setTextSize(12);
}
else if (v.get(i) instanceof LinearLayout) {
LinearLayout layout = (LinearLayout) v.get(i);
layout.setBackgroundColor(getBottomBarBackground());
}
else if (v.get(i) instanceof TextView) {
TextView layout = (TextView) v.get(i);
layout.setTextColor(getTextColor());
}
}
}
private Drawable getShape(int col){
GradientDrawable gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.TL_BR, new int[] { col,
col, col});
gradientDrawable.setGradientType(GradientDrawable.RECTANGLE);
gradientDrawable.setCornerRadii(getRandomFloatArray());
gradientDrawable.setGradientCenter(0.0f, 0.45f);
gradientDrawable.setStroke(1, Color.WHITE);
gradientDrawable.setSize(60, 30);
return gradientDrawable;
}
private float [] getRandomFloatArray(){
float[] floats = new float[8];
for (int i =0; i < floats.length; i++){
floats[i] = 2;
}
return floats;
}
public int getTopBarBackground() {
return topBarBackground;
}
public void setTopBarBackground(int topBarBackground) {
this.topBarBackground = topBarBackground;
}
public int getBottomBarBackground() {
return bottomBarBackground;
}
public void setBottomBarBackground(int bottomBarBackground) {
this.bottomBarBackground = bottomBarBackground;
}
public int getButtonBackground() {
return buttonBackground;
}
public void setButtonBackground(int buttonBackground) {
this.buttonBackground = buttonBackground;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
}
I was changing the colors for the views you can set the drawables as well now use this in your activities onResume function
private void changeColor() {
// TODO Auto-generated method stub
ArrayList<View> v = new ArrayList<View>();
v.add(topBar);
v.add(bottomBar);
v.add(updateBio);
v.add(updateEvents);
v.add(updateGallery);
v.add(updatePersonalStyle);
v.add(updateVip);
v.add(updateStatus);
v.add(NameLink);
v.add(changeProfilePicture);
ThemeManager theme = ThemeManager.getInstance();
theme.setThemeCode(PreferenceManager.getDefaultSharedPreferences(
getApplicationContext()).getInt("Theme_Color",
Color.parseColor("#7606a5")));
theme.setTheme(v);
}
just call this function in the onResume
Related
I am using viewpager in my application and i want to make only one view Swipeable . Is it possible to do so.
I don't want the buttons at the bottom move when i swipe i only want the textview to change.
Any way can anyone help i searched a lot but couldn't find anything.
Here is my code.
There is a lot of code i can't paste all of it here.
Here is the link to the rest of it.
ViewPagerAdapter.java
public class ViewPagerAdapter extends PagerAdapter {
private Activity activity;
private Cursor cursor;
private int i = 0;
private int f = 0;
OnItemClickListener mOnItemClickListener;
public ViewPagerAdapter(Activity activity, Cursor cursor) {
this.activity = activity;
this.cursor = cursor;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
}
#Override
public int getCount() {
return cursor.getCount();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
#NonNull
#Override
public Object instantiateItem(#NonNull final ViewGroup container, final int position) {
final Context context = container.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.quote_detail_viewpager, container, false);
final TextView tvQuotes;
final ImageButton favouriteBtn, shareBtn, copyBtn, bgBtn, fontBtn;
tvQuotes = v.findViewById(R.id.vp_quotes);
favouriteBtn = v.findViewById(R.id.vp_fav);
shareBtn = v.findViewById(R.id.vp_share);
copyBtn = v.findViewById(R.id.vp_copy);
bgBtn = v.findViewById(R.id.vp_bg);
fontBtn = v.findViewById(R.id.vp_font);
int[] fonts = {
R.font.architects_daughter, R.font.artifika, R.font.carter_one,
R.font.expletus_sans, R.font.fredoka_one, R.font.graduate, R.font.jose,
R.font.magnolia, R.font.oswald, R.font.quicksand_bold, R.font.righteous,
R.font.salsa, R.font.schoolbell, R.font.sofadi_one
};
cursor.moveToPosition(position);
String id = cursor.getString(0);
String quote = cursor.getString(1);
String author = cursor.getString(2);
String text = quote + "\n \n - "+ author;
if (new DatabaseHelper(context).isFavourite(id)) {
favouriteBtn.setImageResource(R.drawable.ic_favorite);
}
tvQuotes.setText(text);
tvQuotes.setTypeface(PrefUtils.getTypefaceFromPrefs(context));
favouriteBtn.setOnClickListener(view ->
UtilsHelper.addOrDeleteFavourite(context, favouriteBtn, id, quote, author));
shareBtn.setOnClickListener(view -> UtilsHelper.shareTextIntent(context, text));
copyBtn.setOnClickListener(view -> UtilsHelper.copyText(context, text));
bgBtn.setOnClickListener(view -> mOnItemClickListener.onItemClick(view));
fontBtn.setOnClickListener(view -> {
int j = f++;
if (j < fonts.length) {
PrefUtils.setTypefaceFromPrefs(context, fonts[j]);
tvQuotes.setTypeface(PrefUtils.getTypefaceFromPrefs(context));
notifyDataSetChanged();
}
if (f == fonts.length) {
f = 0;
}
});
container.addView(v);
return v;
}
#Override
public int getItemPosition(#NonNull Object object) {
return POSITION_NONE;
}
#Override
public void destroyItem(ViewGroup container, int position, #NonNull Object object) {
container.removeView((View) object);
}
public interface OnItemClickListener {
void onItemClick(View view);
}
}
DetailActivity.java
public class QuoteDetailActivity extends AppCompatActivity {
// Max swipe ad interval
private final int MAX_AD_COUNT = 10;
// count swipes
private int SWIPE_COUNT = 0;
// Min swipe ad interval
private int MIN_AD_COUNT = 6;
private int i = 0;
private InterstitialAd mInterstitialAd;
ViewPagerAdapter pagerAdapter;
RelativeLayout rootLayout;
int[] backgrounds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Objects.requireNonNull(getSupportActionBar()).hide(); //hide the title bar
setContentView(R.layout.activity_quote_detail);
showInterstitialAd();
// String extras
String incomingActivity = getIntent().getStringExtra(Constants.STRING_EXTRA_INCOMING_ACTIVITY);
int position = getIntent().getIntExtra(Constants.STRING_EXTRA_ADAPTER_POSITION, 0);
DatabaseHelper mDBHelper = new DatabaseHelper(this);
ViewPager viewPager = findViewById(R.id.single_quote_viewpager);
backgrounds = BackgroundUtils.getAllBackgrounds();
rootLayout = findViewById(R.id.root_container);
rootLayout.setBackgroundResource(BackgroundUtils.getBackground(position));
FrameLayout adContainerView = findViewById(R.id.ad_view_container);
adContainerView.post(() ->
AdHelper.loadBanner(this, adContainerView, viewPager));
assert incomingActivity != null;
if (incomingActivity.contains(Constants.ACTIVITY_QUOTES)) {
pagerAdapter = new ViewPagerAdapter(this, mDBHelper.getAllQuotes());
} else if (incomingActivity.contains(Constants.ACTIVITY_FAVOURITE)) {
pagerAdapter = new ViewPagerAdapter(this, mDBHelper.getFavourites());
}
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(position); // Setup recycleView Item position
pagerAdapter.setOnItemClickListener(new ViewPagerAdapter.OnItemClickListener() {
#Override
public void onItemClick(View view) {
changeBackground();
}
});
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
int count = SWIPE_COUNT++;
if (count >= MIN_AD_COUNT) {
if (mInterstitialAd != null) {
mInterstitialAd.show(QuoteDetailActivity.this);
SWIPE_COUNT = 0;
}
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void changeBackground() {
int j = i++;
if (j < backgrounds.length) {
rootLayout.setBackgroundResource(backgrounds[j]);
}
if (i == backgrounds.length) {
i = 0;
}
}
private void showInterstitialAd() {
MobileAds.initialize(this, initializationStatus -> {
});
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(this, getString(R.string.interstitial_ad_unit),
adRequest, new InterstitialAdLoadCallback() {
#Override
public void onAdLoaded(#NonNull InterstitialAd interstitialAd) {
// The mInterstitialAd reference will be null until
// an ad is loaded.
mInterstitialAd = interstitialAd;
mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() {
#Override
public void onAdDismissedFullScreenContent() {
// Called when fullscreen content is dismissed.
if (MIN_AD_COUNT < MAX_AD_COUNT) {
MIN_AD_COUNT++;
}
}
#Override
public void onAdShowedFullScreenContent() {
// Called when fullscreen content is shown.
// Make sure to set your reference to null so you don't
// show it a second time.
mInterstitialAd = null;
}
});
}
#Override
public void onAdFailedToLoad(#NonNull LoadAdError loadAdError) {
// Handle the error
mInterstitialAd = null;
}
});
}
}
Sure, something like the below pseudo_xml
<Parent View> -- background set to image
<ViewPager> -- only this part is swipable
<View Containing Buttons Fixed To The Bottom Of Parent/>
</Parent View>
Straight to the point. I am trying to show coachmark series using ShowcaseView library by amlcurran: https://github.com/amlcurran/ShowcaseView
I can't get the coachmark showing. The problem is runCoachMark() method always returning null. runCoachMark() method run right after notifyDatasetChaned() on mMainAdapter.
I have tried to use Handler().postDelayed() and Thread.sleep() with no success.
Anyone can explain why it is happening and some solutions for this problem. Thank you.
private static final int COACHMARK_A = -3;
private static final int COACHMARK_B = -2;
private static final int COACHMARK_C = -1;
// ... some other coachmark type
private static final int END_COACHMARK = 0;
private static final int SCROLL_OFFSET = 56;
private static final long COACHMARK_DELAY = 200L;
private void runCoachMark(int type) {
if (type == END_COACHMARK) {
return;
}
View v = getCoachMarkView(type);
if (v == null) {
return;
}
showCoachMark(getActivity(), v, type);
}
#Nullable
private View getCoachMarkView(final int type) {
safeScrollTo(getPos(type), SCROLL_OFFSET);
return mMainList.getChildAt(0).findViewById(getCoachMarkId(type));
}
private void safeScrollTo(final int pos, final int offset) {
mMainList.setLayoutFrozen(true);
mLayoutManager.scrollToPositionWithOffset(pos, offset);
mMainList.setLayoutFrozen(false);
}
private int getCoachMarkId(int type) {
int id;
switch (type) {
case COACHMARK_A:
id = R.id.A;
break;
case COACHMARK_B:
id = R.id.B;
break;
case COACHMARK_C:
id = R.id.C;
break;
// ... some other types
default:
id = 0;
break;
return id;
}
private int getPos(int type) {
int pos;
switch (type) {
case COACHMARK_A:
pos = 1;
break;
case COACHMARK_B:
pos = 4;
break;
case COACHMARK_C:
pos = 5;
break;
// ... some other cases
default:
pos = 0;
break;
}
return pos;
}
private void showCoachMark(final Context context, final View v, final int type) {
new ShowcaseView.Builder(getActivity())
.setTarget(new ViewTarget(v.getId(), (Activity) context))
.setContentTitle(getTitle(type))
.setContentText(getDescription(type))
.setShowcaseDrawer(new CustomShowcaseView(v))
.setShowcaseEventListener(new OnShowcaseEventListener() {
#Override
public void onShowcaseViewHide(ShowcaseView showcaseView) {
}
#Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
runCoachMark(type++);
}
}, COACHMARK_DELAY);
}
#Override
public void onShowcaseViewShow(ShowcaseView showcaseView) {
}
#Override
public void onShowcaseViewTouchBlocked(MotionEvent motionEvent) {
}
})
.build();
}
}
I would share with you a new way to use showcaseview dynamically with recursive method
1) Create your ViewTargets, for example 4 targets (you can create n targets) and put targets into an array declared as a private attribute in your Activity class : private ViewTarget[] targets;
final ViewTarget target1 = new ViewTarget(textview1);
final ViewTarget target2 = new ViewTarget(textview2);
final ViewTarget target3 = new ViewTarget(textview3);
final ViewTarget target4 = new ViewTarget(textview4);
targets = new ViewTarget[] { target1, target2,target3,target4};
2) Create the recursive method :
private void toStep(final String title, final String description,Target target, final int i) {
final ShowcaseView.Builder showCaseBuilder = new ShowcaseView.Builder(ShowCaseActivity.this);
showCaseBuilder.setTarget(targets[i]);
showCaseBuilder.setContentTitle(title.replace("[i]", ""+i));
showCaseBuilder.setContentText(description.replace("[i]", ""+i));
showCaseBuilder.setShowcaseEventListener(new OnShowcaseEventListener() {
#Override
public void onShowcaseViewTouchBlocked(MotionEvent motionEvent) {
}
#Override
public void onShowcaseViewShow(ShowcaseView showcaseView) {
}
#Override
public void onShowcaseViewHide(ShowcaseView showcaseView) {
try {
toStep(title, description, targets[i+1], i+1);
} catch(Exception ex) {
}
}
#Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
}
});
showCaseBuilder.build();
}
3) Finally you can call the method that displays Showcases :
toStep("Title for showcase [i]", " Description for showcase [i] ",targets[0], 0);
I hope this will be helpful for you :)
I am using a RecyclerView inside a Fragment to display a list of categories ( as shown in the images). When a category is selected, a new Activity starts with a RecyclerView. Each item from the list has a TextView and an icon for favorite ( the star from the top-right corner ). Once the favorite icon is pressed, the TextView will be saved to another Activity called Favorites.
The problem: let's say that I select Category A and I press the favorite button for the first 2 items. Everything looks good, the items are saved to Favorites. If I select Category B, bamm, I find the first 2 items selected...I go to Category C, same thing!
So if I check the favorite button once, it checks for all Adapters, like they're communicating. Why is this happening?
Although the favorite buttons are checked, I can't find the TextView's from Category B or C in the Favorites activity.
The Activity that starts when a category item is selected:
public class CategoriesDetailActivity extends AppCompatActivity {
Adapter0 ca0;
RecyclerView recList;
public CategoriesDetailActivity() {
// Required empty public constructor
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.categories_detail_activity);
Bundle bundle = this.getIntent().getExtras();
// Bundle bundle = this.getArguments();
bundle.getInt("id");
int position = bundle.getInt("id");
if (bundle.containsKey("id")) {
position = bundle.getInt("id");
} else {
this.finish();
}
recList = (RecyclerView) findViewById(R.id.cardList);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
switch (position) {
case 0:
ca0 = new Adapter0(this, createList0(99));
recList.setAdapter(ca0);
break;
case 1:
ca0 = new Adapter0(this, createList1(80));
recList.setAdapter(ca0);
break;
...
}
}
private List<BeanSampleList> createList0(int size) {
List<BeanSampleList> result = new ArrayList<>();
for (int i = 0; i <= size; i++) {
BeanSampleList ci = new BeanSampleList();
ci.title = DataText.Text1[i];
ci.id = i;
result.add(ci);
}
return result;
}
private List<BeanSampleList> createList1(int size) {
List<BeanSampleList> result = new ArrayList<>();
for (int i = 0; i <= size; i++) {
BeanSampleList ci = new BeanSampleList();
ci.title = DataText.Text2[i];
ci.id = i;
result.add(ci);
}
return result;
}
#Override
public void onResume() {
super.onResume();
if (recList.getAdapter() == ca0) {
ca0.notifyDataSetChanged();
} if (recList.getAdapter() == ca1) {
ca1.notifyDataSetChanged();
} else {
// nothing
}
}
}
The Adapter class:
public class Adapter0 extends RecyclerView.Adapter<Adapter0 .ContactViewHolder> {
private Context context;
List<BeanSampleList> postBeanSampleList;
SharedPreference sharedPreference;
BeanSampleList beanSampleList;
public Adapter0 (Context context, List<BeanSampleList> postBeanSampleList) {
this.context = context;
this.postBeanSampleList = postBeanSampleList;
sharedPreference = new SharedPreference();
}
#Override
public int getItemCount() {
return postBeanSampleList.size();
}
public Object getItem(int position) {
return postBeanSampleList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public void onBindViewHolder(final ContactViewHolder holder,final int i) {
beanSampleList = (BeanSampleList) getItem(i);
holder.vName.setText(beanSampleList.getTitle());
if (checkFavoriteItem(beanSampleList)) {
holder.btnFavourite.setLiked(true);
holder.btnFavourite.setTag("active");
} else {
holder.btnFavourite.setLiked(false);
holder.btnFavourite.setTag("deactive");
}
}
#Override
public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.categories_detail_adapter, viewGroup, false);
return new ContactViewHolder(itemView);
}
public class ContactViewHolder extends RecyclerView.ViewHolder implements OnLikeListener {
protected TextView vName;
protected LikeButton btnFavourite;
public ContactViewHolder(View v) {
super(v);
vName = (TextView) v.findViewById(R.id.t1);
btnFavourite = (LikeButton) v.findViewById(R.id.favouritesToggle);
btnFavourite.setOnLikeListener(this);
}
#Override
public void liked(LikeButton likeButton) {
final int position = getAdapterPosition();
if (likeButton.getId() == btnFavourite.getId()) {
String tag = btnFavourite.getTag().toString();
if (tag.equalsIgnoreCase("deactive")) {
sharedPreference.addFavorite(context, postBeanSampleList.get(position));
btnFavourite.setTag("active");
btnFavourite.setLiked(true);
}
Snackbar snackbar = Snackbar
.make(likeButton, "Added to Favorites!", Snackbar.LENGTH_SHORT);
snackbar.show();
}
}
#Override
public void unLiked(LikeButton likeButton) {
final int position = getAdapterPosition();
if (likeButton.getId() == btnFavourite.getId()) {
sharedPreference.removeFavorite(context, postBeanSampleList.get(position));
btnFavourite.setTag("deactive");
btnFavourite.setLiked(false);
Snackbar snackbar = Snackbar
.make(likeButton, "Removed from Favorites!", Snackbar.LENGTH_SHORT);
snackbar.show();
}
}
}
public boolean checkFavoriteItem(BeanSampleList checkProduct) {
boolean check = false;
List<BeanSampleList> favorites = sharedPreference.loadFavorites(context);
if (favorites != null) {
for (BeanSampleList product : favorites) {
if (product.equals(checkProduct)) {
check = true;
break;
}
}
}
return check;
}
}
For the past 2 days I've been trying to fix this but I just can't figure out what's causing this. I also tried to use different Adapters for each position but with no success.
public class BeanSampleList {
public int id;
public String title;
public String subTitle;
public String bottomTitle;
public String imageView;
public BeanSampleList() {
super();
}
public BeanSampleList(int id, String title, String subTitle, String bottomTitle, String imageView) {
super();
this.id = id;
this.title = title;
this.subTitle = subTitle;
this.bottomTitle = bottomTitle;
this.imageView = imageView;
}
public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleBottom() {
return bottomTitle;
}
public void setTitleBottom(String bottomTitle) {
this.bottomTitle = bottomTitle;
}
public String getImageView() {
return imageView;
}
public void setImageView(String imageView) {
this.imageView = imageView;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BeanSampleList other = (BeanSampleList) obj;
if (id != other.id)
return false;
return true;
}
}
Thank you so much and sorry for my english.
I think the error is in your id generation for BeanSampleList
private List<BeanSampleList> createList0(int size) {
List<BeanSampleList> result = new ArrayList<>();
for (int i = 0; i <= size; i++) {
BeanSampleList ci = new BeanSampleList();
ci.title = DataText.Text1[i];
ci.id = i;
result.add(ci);
}
return result;
}
private List<BeanSampleList> createList1(int size) {
List<BeanSampleList> result = new ArrayList<>();
for (int i = 0; i <= size; i++) {
BeanSampleList ci = new BeanSampleList();
ci.title = DataText.Text2[i];
ci.id = i;
result.add(ci);
}
return result;
}
You need to generate unique id for your BeanSamleList objects in createList* method. As in your current code the objects are the same from the equals method side (their id are from 0 to list_size range).
Or add some unique modifier to compare in equal, like add the position of parent list
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BeanSampleList other = (BeanSampleList) obj;
if (id != other.id)
return false;
if (listId != other.listId)
return false;
return true;
}
You need to find a different way to uniquely identify each BeanSampleList element. Just matching id is not good enough. Perhaps you could also match the titles if you know they will be unique. Or generate unique Ids for each of these elements say by dividing the integer domain in different ranges e.g. 1 to 1000000 is for category 1, 1000001 to 2000000 for category 2 and so on.
i have been trying to implement the endless scroll feature for my product listing page of a ecommmerce app. The grids show the details of the items and when i scroll to the bottom i need to show a progress bar and then append the new grid of items.
The api call works like this, I need to send a start_row_number and limit, which will send me all the items from the start_row_number to limit. Example: start_row_number = 0 and limit = 10. This will return items from 0 to 10
After that i need to load more items when the user reaches the bottom of the grid, and append it to the gridview. So i will send start_row_number = 10 and limit = 10, this will return items form 10 to 20.
As of now, i can get the items from 0 to 10 but not after that. How can i create the endless scroll feature and make everything such that it doesn't give me error such as 'too much work on the main thread'
Here is my MainActivity:
public class ProductListing extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.product_listing_act);
init();
}
public void productListingApiCall(ProductListingCondtionModel productListingCondtionModel) {
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(productListingCondtionModel.getBase_url()).setLogLevel(RestAdapter.LogLevel.FULL).build();
final ProductListingApi productListingApi =
restAdapter.create(ProductListingApi.class);
productListingApi.getFeed(productListingCondtionModel.getFile(),
productListingCondtionModel.getOperation_condition(),
productListingCondtionModel.getSearch_string_condition(),
productListingCondtionModel.getMinprice_condition(),
productListingCondtionModel.getMaxprice_condition(),
productListingCondtionModel.getMincusratings_condition(),
productListingCondtionModel.getMaxcusratings_condition(),
productListingCondtionModel.getDiscount_condition(),
productListingCondtionModel.getCatids_condition(),
productListingCondtionModel.getBrands_condition(),
productListingCondtionModel.getAffids_condition(),
productListingCondtionModel.getStart_row_condition(),
productListingCondtionModel.getLimit(),
productListingCondtionModel.getOrderby_condition(),
productListingCondtionModel.getSortby_condition(), new Callback<ProductListingPojo>() {
#Override
public void success(ProductListingPojo productListingPojo, Response response) {
final ProductListingPojo product = productListingPojo;
new Thread(new Runnable() {
#Override
public void run() {
String[] t = Arrays.copyOf(product.getTitle(),
product.getTitle().length);
int[] p = Arrays.copyOf(product.getSellingprice(),
product.getSellingprice().length);
int[] m = Arrays.copyOf(product.getMrp(),
product.getMrp().length);
int[] d = Arrays.copyOf(product.getDiscountpercent(),
product.getDiscountpercent().length);
String[] i = Arrays.copyOf(product.getProductimageSmall1(),
product.getProductimageSmall1().length);
for(int j = 0; j < t.length; j++) {
CategoryAllApi categoryAllApi = new CategoryAllApi();
categoryAllApi.setTitle(t[j]);
categoryAllApi.setPrice(p[j]);
categoryAllApi.setMrp(m[j]);
categoryAllApi.setDiscount(d[j]);
categoryAllApi.setImage(i[j]);
arrayList.add(categoryAllApi);
}
}
}).run();
setAdapter();
}
#Override
public void failure(RetrofitError error) {
tv_title_header.setText(error.getMessage());
Log.e("error", error.getMessage());
}
});
}
void setAdapter() {
adapter = new ProductListingGridAdapter(this, arrayList);
gv_product_listing_act.setAdapter(adapter);
}
}
Heres the Adapter:
public class ProductListingGridAdapter extends BaseAdapter {
public ProductListingGridAdapter(ProductListing productListing, ArrayList<CategoryAllApi> arrayList) {
this.arrayList= arrayList;
context = productListing;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public class Holder
{
ImageView im_pic;
TextView tv_title, tv_price, tv_mrp, tv_discount;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
GridView grid = (GridView) parent;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
grid.setColumnWidth(width);
grid.setNumColumns(2);
int size = grid.getRequestedColumnWidth() / 2 ;
Double d = new Double(size * 2);
int h = d.intValue();
Holder holder = new Holder();
View rowView;
int index = grid.getFirstVisiblePosition();
View v = grid.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - grid.getPaddingTop());
grid.setSelectionFromTop(index, top);
rowView = inflater.inflate(R.layout.product_listing_gv_items_lay, null);
rowView.setLayoutParams(new GridView.LayoutParams(size, h));
holder.im_pic = (ImageView) rowView.findViewById(R.id.im_product_listing_gv_items_lay_pic);
holder.tv_title = (TextView) rowView.findViewById(R.id.tv_product_listing_gv_items_lay_title);
holder.tv_price = (TextView) rowView.findViewById(R.id.tv_product_listing_gv_items_lay_price);
holder.tv_mrp = (TextView) rowView.findViewById(R.id.tv_product_listing_gv_items_lay_mrp);
holder.tv_discount = (TextView) rowView.findViewById(R.id.tv_product_listing_gv_items_lay_discount);
holder.tv_title.setTypeface(EasyFonts.robotoMedium(rowView.getContext()));
holder.tv_price.setTypeface(EasyFonts.robotoBlack(rowView.getContext()));
holder.tv_mrp.setTypeface(EasyFonts.robotoLight(rowView.getContext()));
holder.tv_mrp.setPaintFlags(holder.tv_mrp.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
holder.tv_discount.setTypeface(EasyFonts.robotoLight(rowView.getContext()));
categoryAllApi = arrayList.get(position);
Ion.with(holder.im_pic).load(categoryAllApi.getImage());
holder.tv_title.setText(categoryAllApi.getTitle());
holder.tv_price.setText("Rs. " + categoryAllApi.getPrice());
holder.tv_mrp.setText("Rs. " + categoryAllApi.getMrp());
holder.tv_discount.setText("" + categoryAllApi.getDiscount() + "%");
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, ProductDetails.class);
Bundle bundle = new Bundle();
bundle.putString("operation", "");
bundle.putString("productkey", "");
intent.putExtras(bundle);
context.startActivity(intent);
}
});
return rowView;
}
}
Heres the CategoryApiCall.java:
public class CategoryAllApi {
private String title, image;
private int price, mrp, discount;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getMrp() {
return mrp;
}
public void setMrp(int mrp) {
this.mrp = mrp;
}
public int getDiscount() {
return discount;
}
public void setDiscount(int discount) {
this.discount = discount;
}
}
I see you have used a GridView.
RecyclerView has been introduced by Google and overcomes flaws of listview and Gridview which filled the ram with junk and made app clunky.
Use RecyclerView with GridLayoutManager. Also, research endless scroll in RecyclerView (which is pretty easy to implement).
I strongly recommend this for your app, since I have tried the same and result is outstanding. App is faster, ram becomes light, and scrolling is great. Also there are many features like the recyclerView object will offer. About time Google took care of such things and raise app quality.
Process may look like a task but in long run it will help you and the app users a lot.
I'm actually trying to display the line numbering at the left of an EditText as shown in the figure.
The problem is that whenever a new line is added or removed to the file, it take a while to recalculate the string containing the line numbering.
What I do is the following: whenvere there is a type, I check whether the line count of the EditText has changed, if it is the case I just append the missing line at the end of the TextView showing the line numbering.
So if we take the piece of code in the image and press the new line key, my code get the line count (14 since we added a line) and append 14 + System.lineSeparator() to the TextView by using linesTextView.append(newText).
As said the application is lagging. Is there a way to efficently modify the content of a TextView?
Another solution that came in my mind was to use a TextView for each line number and just remove or add a new TextView when the line count of the content has changed. The problem about that is that I cannot make the TextViews be aligned with the lines of the EditText.
Thank you
EDIT:
Forgot to add the code
public class CodeEditView extends LinearLayout implements TouchEditText.TouchEditTextListener{
private View root;
private InternalFile file;
private TouchEditText code;
private ScrollView scroll;
private int linesCount;
private TextView lines;
private int currentStartLine;
private int currentEndLine;
public CodeEditView(Context context) {
super(context);
init(null, context);
}
public CodeEditView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, context);
}
private void init(AttributeSet attrs, Context context) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
root = layoutInflater.inflate(R.layout.edit_code_layout, this).findViewById(R.id.scroll_view);
this.lines = (TextView) findViewById(R.id.edit_code_lines_view);
this.code = (TouchEditText) findViewById(R.id.edit_code_content_view);
code.setRoot(root);
code.setListener(this);
linesCount = 0;
scroll = (ScrollView) findViewById(R.id.scroll_view);
scroll.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
// int scrollY = scroll.getScrollY();
// if(scrollY != 0) {
// code.scrollEvent();
// if(currentStartLine < code.getCurrentStartLine()) {
//
// String c = lines.getText().toString();
// String cc = c.replaceFirst("\\d+", " ");
// cc += Integer.toString(code.getCurrentEndLine()+10) + System.lineSeparator();
// lines.setText(cc);
// currentStartLine = code.getCurrentStartLine();
//
// } else {
//// CharSequence c = lines.getText();
//// lines.setText(lines.getText().);
// }
// }
int scrollY = scroll.getScrollY();
if(scrollY != 0) {
code.scrollEvent();
}
}
});
}
public void setFile(InternalFile file) {
this.file = file;
}
public void setLexer(Lexer lexer) {
code.setLexer(lexer);
}
private void initLines() {
// currentStartLine = code.getCurrentStartLine();
// currentEndLine = code.getCurrentEndLine();
// int usedLines = code.getLineCount();
// if(usedLines != linesCount) {
//
// String text = "";
//
// for(int i = currentStartLine; i <= currentEndLine+10; i++) {
// text += Integer.toString(i) + System.lineSeparator();
// }
// lines.setText(text);
// linesCount = usedLines;
// }
int usedLines = code.getLineCount();
String text = "";
for(int i = 1; i <= usedLines; i++) {
text += Integer.toString(i) + System.lineSeparator();
}
Log.d("TEXT", Integer.toString(usedLines));
lines.setText(text);
linesCount = usedLines;
}
public void initText(String content) {
code.initText(content);
code.post(new Runnable() {
#Override
public void run() {
initLines();
}
});
}
public void setFont(Typeface typeFace) {
this.lines.setTypeface(typeFace);
this.code.setTypeface(typeFace);
}
#Override
public void onTyped(String text) {
EventBus.getDefault().post(new UpdateCacheFileEvent(text,file));
setLines();
}
public void forceSyntax(Syntax s) {
code.forceSyntax(s);
}
private void setLines() {
int usedLines = code.getLineCount();
if(usedLines > linesCount) {
lines.append(Integer.toString(usedLines) + System.lineSeparator());
linesCount = usedLines;
} else {
}
}
}