There is such issue, I have horizontal RecyclerView where each cell less than width of screen.
So I found a solution here
RecyclerVIew auto scroll to display all the elements as in News Feed etc.,
All work excellent if one cell take whole width of the screen otherwise(if each cell take 95% of screen width) every auto swipe place the cell at the beginner of screen (right side) and it is logical. So at the end of one visible cell it is start of another cell
it is doesn't looks good. I need this cell to be at the middle of the screen like this.
I need to see previous cell - current - next one
Now I would like to explain some magic how I make current smooth scroll (as I mentioned at link above)
this method in my CustomLinnearLayoutManager
#Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position)
{
LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext())
{
#Override
public PointF computeScrollVectorForPosition(int targetPosition)
{
return SmoothLayoutManager.this.computeScrollVectorForPosition(targetPosition);
}
#Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
{
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
But this method works without offset
I found out one more method that can provide desired offset
scrollToPositionWithOffset(final int position, final int offset)
And it is looks like exactly what I need , but this method works without smooth animation.
So, eventually my question is : how to apply animation logic from first method to second (that with offset)
Feel free to ask
To auto snapping and showing one item at center of RecyclerView, simply you need to use LinearSnapHelper like following:
LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
If you want to scroll to a specific item programmatically, LinearSnapHelper handles snapping functionality too.
SmoothScroller smoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
#Override
protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_ANY;
}
#Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return 120f / displayMetrics.densityDpi;
}
};
...
smoothScroller.setTargetPosition(position);
recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
Here is the visual result:
.
..................Manually Scrolling...........................Programmatically Scrolling..........
Eventually, I found the way thanks a lot to #aminography for his answer and also one more answer help me a lot
https://stackoverflow.com/a/39654328
Actually now I have such implementation
My custom LinnearLayoutManager implementation
public class SmoothLayoutManager extends LinearLayoutManager
{
public static final int X_25 = 25;
public static final int X_200 = 200;
public static final float DEFAULT = X_25;
/**
* !! IMPORTANT !!
* If you need to add new value, don't forget add it here also
*/
#Retention(RetentionPolicy.SOURCE)
#IntDef({X_25, X_200})
private #interface Speed
{
}
private static float MILLISECONDS_PER_INCH = DEFAULT;
public SmoothLayoutManager(Context context)
{
super(context);
}
public SmoothLayoutManager(Context context, int orientation, boolean reverseLayout)
{
super(context, orientation, reverseLayout);
}
public SmoothLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
{
super(context, attrs, defStyleAttr, defStyleRes);
}
public SmoothLayoutManager setSpeedOfSmooth(#Speed int iSpeed)
{
MILLISECONDS_PER_INCH = iSpeed;
return this;
}
#Override
public void scrollToPositionWithOffset(final int position, final int offset)
{
super.scrollToPositionWithOffset(position, offset);
}
#Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position)
{
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(recyclerView.getContext())
{
#Override
public PointF computeScrollVectorForPosition(int targetPosition)
{
return SmoothLayoutManager.this.computeScrollVectorForPosition(targetPosition);
}
#Override
protected int getVerticalSnapPreference()
{
return LinearSmoothScroller.SNAP_TO_ANY;
}
#Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
{
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
#Override
public int calculateDtToFit(final int viewStart, final int viewEnd, final int boxStart, final int boxEnd, final int snapPreference)
{
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
}
And this is how I make set
private void setRv(Context iC)
{
RecyclerView.Adapter adapter = new UpSaleInnerAdapter(mPicasso, mInflater, iLink -> mListener.onButtonClick(iLink));
mRv.setLayoutManager(new SmoothLayoutManager(iC, LinearLayoutManager.HORIZONTAL, false).setSpeedOfSmooth(SmoothLayoutManager.X_200));
mRv.setAdapter(adapter);
SnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(mRv);
}
Note :
I noticed that sometimes if you make fast swipe, so SnapHelper a little bit confused and pass more cells that need... like a turbo mode :)
If someone will find how to fix it, let me know.
Thanks!
Related
I want a text inside a textbox to scroll to end and then restart.
Using marquee scrolls the whole text until the first letter reaches the "start point", but I want the text only to scroll until the last letter of the text becomes visible, then pause and the text should jump to start and start scrolling again.
Is there a way to do this. I have search but I can't find something that works for me.
Thanks,
Sebi
I am not aware of any way to configure a TextView to take on the marquee behavior that you are seeking. The Stack Overflow Q/A I referred you to in the comments does translate the entire TextView. I think that this will work as a marquee if you set the TextView within a ViewGroup such that the TextView is clipped. You can also do you own clipping. You would have to try this to see if it would work. If this does work, it may be sufficient for your needs, but you may be missing the fading edge and maybe some other characteristics of true marquee scrolling. Also, some other characteristics of the TextView such as shadows, borders and backgrounds might not look right.
The contents of the TextView is animated by the TextView code itself through canvas translation for marquee scrolling. See here.
if (isMarqueeFadeEnabled()) {
if (!mSingleLine && getLineCount() == 1 && canMarquee()
&& (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != Gravity.LEFT) {
final int width = mRight - mLeft;
final int padding = getCompoundPaddingLeft() + getCompoundPaddingRight();
final float dx = mLayout.getLineRight(0) - (width - padding);
canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
if (mMarquee != null && mMarquee.isRunning()) {
final float dx = -mMarquee.getScroll();
canvas.translate(layout.getParagraphDirection(0) * dx, 0.0f);
}
}
You can also consider writing a custom TextView and doing your own text scrolling. You can look to the TextView code itself for some tips on how you might do it. I think writing your own TextView would have better results. (IMO)
I have rewrite the Code from the GitHub Project here (which was posted in the comment from Cheticamp) to java and shorten it to my needs. Now it starts the animation infinite.
Here the java code:
MarqueeTextView.java:
public class MarqueeTextView extends androidx.appcompat.widget.AppCompatTextView {
private final Scroller mScroller;
private int mDelay;
private int mDuration;
private final Handler mHandler = new Handler();
private final Runnable mAnimateRunnable = new Runnable() {
#Override
public void run() {
//check if Animation is needed otherwise check next cycle (if text has changed for example)
if (getTextViewWidthWithPadding() < getTextWidth()) {
mScroller.startScroll(getStartX(), 0, 0, 0, 0);
invalidate();
int direction = getLayout().getParagraphDirection(0);
mScroller.startScroll(getStartX(), 0, (getTextWidth() - getTextViewWidthWithPadding()) * direction, 0, mDuration);
}
mHandler.postDelayed(mAnimateRunnable, mDelay);
}
};
public MarqueeTextView(Context context) {
this(context, null);
}
public MarqueeTextView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
mScroller = new Scroller(context, new LinearInterpolator());
setScroller(mScroller);
}
private int getTextWidth() {
String text = getText().toString();
TextPaint paint = getPaint();
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
return bounds.width();
}
private int getTextViewWidthWithPadding() {
return getWidth() - (getPaddingStart() + getPaddingEnd());
}
private int getStartX() {
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
int lineRight = (int) getLayout().getLineRight(0);
if (isRtl) {
return lineRight - getTextViewWidthWithPadding();
} else {
return 0;
}
}
public void startAnimation(int delay, int duration) {
mDelay = delay;
mDuration = duration;
mHandler.postDelayed(mAnimateRunnable, delay);
}
}
activity_main.xml:
<MarqueeTextView
android:id="#+id/name"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:ellipsize="none"
android:singleLine="true"
android:text="1. Simple text that shows how to use custom marquee"
/>
MainActivty.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((MarqueeTextView)findViewById(R.id.name)).startAnimation(3000, 2000);
}
so i have been trying to make this BMI calculator in android studio, where your BMI will instantly get calculated when you drag Progress-bar to any value .
To execute this, what i did was-
inside the the Bundle class,
i directly declared 2 variable and assigned one of them to get the data from the Height progress bar and another to get the data from weight progress bar.
and then i wrote the typical code for the calculation and the text setting.
And it did not work
For myself being a very new to this, i really cant find my mistake here.
so as a result what i got was- a still BMI which was the result for the initial value of the progress-bar that i have set for the height and weight.
i am getting a feeling that i made a very silly mistake somewhere that i still can not notice.
Would you be kind enough to point that out?
the Java code that i have used is below, please check it-
The code for the BMI is at the end. I feel the problem is lying there.
here is the screenshot of the app-
screenshot2
screenshot1
here is my code--
public class MainActivity extends AppCompatActivity {
TextView mheighttext,mweighttext2,mbmitext,mfunnymsg;
SeekBar mbar1, mbar2;
RelativeLayout mweightlayout, mlayout3;
ImageView mgincbtn1,mgincbtn2,mgdecbtn1,mgdecbtn2;
String mbmi, bmitext;
int wt= 45;
String wtwt="45";
int ht= 158;
String htht="158";
float rslt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
mheighttext=findViewById(R.id.heighttext);
mweighttext2=findViewById(R.id.weighttext2);
mbar1= findViewById(R.id.bar1);
mbar2=findViewById(R.id.bar2);
mgincbtn1=findViewById(R.id.gincbtn1);
mgincbtn2=findViewById(R.id.gincbtn2);
mgdecbtn1=findViewById(R.id.gdecbtn1);
mgdecbtn2=findViewById(R.id.gdecbtn2);
mbmitext=findViewById(R.id.bmitext1);
mfunnymsg=findViewById(R.id.funnymsg);
mbar1.setMax(246);
mbar1.setProgress(160);
mbar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
ht=progress;
htht=String.valueOf(ht);
mheighttext.setText(htht);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mbar2.setMax(244);
mbar2.setProgress(50);
mbar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
wt=progress;
wtwt=String.valueOf(wt);
mweighttext2.setText(wtwt);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
mgincbtn1.setOnClickListener(v -> {
ht=ht+1;
if (ht>=0 && ht<247) {
mbar1.setProgress(ht);
htht = String.valueOf(ht);
mheighttext.setText(htht);
}
});
mgdecbtn1.setOnClickListener(v -> {
ht=ht-1;
if (ht>=0 && ht<247) {
mbar1.setProgress(ht);
htht = String.valueOf(ht);
mheighttext.setText(htht);
}
});
mgincbtn2.setOnClickListener(view -> {
wt=wt+1;
if (wt>=0 && wt<244) {
mbar2.setProgress(wt);
wtwt = String.valueOf(wt);
mweighttext2.setText(wtwt);
}
});
mgdecbtn2.setOnClickListener(v -> {
wt=wt-1;
if (wt>=0 && wt<244) {
mbar2.setProgress(wt);
wtwt = String.valueOf(wt);
mweighttext2.setText(wtwt);
}
});
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
}
}
}
You would want to put the snippet of code that calculates the BMI (perhaps the last 4 lines of code) in both onProgressChanged() to instantly calculate BMI as height/weight gets changed. Since you're setting global variables for both height and weight, you'll get current values for each of them.
You can also make a function for calculating the BMI like this:
private float calculateBMI(int height, int weight) {
float ht = height / 100;
float result = weight / (ht * ht);
return result;
}
and have this function call in both onProgressChanged() like so (for the weight for example):
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
wt = progress;
mweighttext2.setText(String.valueOf(getBMI(ht, progress)));
}
Move this your code...
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
to a method say
public void computeBMI(){
int htt = mbar1.getProgress();
int wtt = mbar2.getProgress();
float httt=htt/100;
rslt= wtt/(httt*httt);
mbmi=Float.toString(rslt);
mbmitext.setText(mbmi);
}
Then add a button in your UI say mCompute. In your oncreate method you can then implement that buttons onClickListener to call computeBMI() above.
That is:
yourButton.setOnclickListener((v)->{
computeBMI();
});
I have been banging my head for days to find some help but maybe I am not looking at the right place.
I am following this article to replicate Twitter like button animation (I don't want to use rebuilt libraries) - http://frogermcs.github.io/twitters-like-animation-in-android-alternative/
I have a Custom View called LikeButtonView
public class LikeButtonView : FrameLayout, View.IOnClickListener
{
private static DecelerateInterpolator DECCELERATE_INTERPOLATOR = new DecelerateInterpolator();
private static AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);
private ImageView ivStar;
private DotsView vDotsView;
private AnimatorSet animatorSet;
public LikeButtonView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
public LikeButtonView(Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Initialize();
}
public void OnClick(View v)
{
vDotsView.setCurrentProgress(0);
animatorSet = new AnimatorSet();
ObjectAnimator starScaleYAnimator = ObjectAnimator.OfFloat(ivStar, ImageView.ScaleYs, 0.2f, 1f);
starScaleYAnimator.SetDuration(350);
starScaleYAnimator.StartDelay = (250);
starScaleYAnimator.SetInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator starScaleXAnimator = ObjectAnimator.OfFloat(ivStar, ImageView.ScaleXs, 0.2f, 1f);
starScaleXAnimator.SetDuration(350);
starScaleXAnimator.StartDelay = (250);
starScaleXAnimator.SetInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator dotsAnimator = ObjectAnimator.OfFloat(vDotsView, DotsView.DOTS_PROGRESS, 0.2f, 1f);
dotsAnimator.SetDuration(900);
dotsAnimator.StartDelay = (50);
dotsAnimator.SetInterpolator(ACCELERATE_DECELERATE_INTERPOLATOR);
animatorSet.PlayTogether(
starScaleYAnimator,
starScaleXAnimator,
dotsAnimator
);
animatorSet.Start();
}
private void Initialize()
{
var INF = LayoutInflater.From(Context).Inflate(Resource.Layout.view_like_button, this, true);
ivStar = INF.FindViewById<ImageView>(Resource.Id.ivStar);
vDotsView = INF.FindViewById<DotsView>(Resource.Id.vDotsView);
SetOnClickListener(this);
}
}
I am also using private DotsView vDotsView which is another custom view, which is a C# Replica of this view https://github.com/frogermcs/LikeAnimation/blob/master/app/src/main/java/frogermcs/io/likeanimation/DotsView.java
In the above link, right at the end, I see the following
public static final Property<DotsView, Float> DOTS_PROGRESS = new Property<DotsView, Float>(Float.class, "dotsProgress") {
#Override
public Float get(DotsView object) {
return object.getCurrentProgress();
}
#Override
public void set(DotsView object, Float value) {
object.setCurrentProgress(value);
}
};
It is Android.Util.Property getting used to get and set the progress
ObjectAnimator dotsAnimator = ObjectAnimator.OfFloat(vDotsView, DotsView.DOTS_PROGRESS, 0.2f, 1f);
I am lost right here, I do not know how to implement this in C#? I have been trying different things but no luck with implementing public static final Property<DotsView, Float> DOTS_PROGRESS with exact parameters.
If anyone can help would be highly appreciated.
If this helps anyone, we can do something like the following
[Register("DOTS_PROGRESS")]
public static Property DotsProgress {
get {
JniObjectReference objectValue = _members.get_StaticFields().GetObjectValue("DOTS_PROGRESS.Landroid/util/Property;");
return Object.GetObject<Property>(objectValue.get_Handle(), 1);
}
}
Found this package which was converted from java to C#
https://www.fuget.org/packages/Karamunting.Android.HanksZyh.SmallBang/1.2.2/lib/monoandroid81/SmallBang.dll/Hanks.Library.Bang/DotsView?code=true
I have created a custom View that will display a circle (the idea is that the user will be able to interact with this "ball" in various ways)
From my main activity class, I want to adjust some of the "ball's" properties, in this case change its color.
My problem is that nothing happens (no errors either, the app runs but doesn't do what I want) when I try to call the various methods from my MainActivity class, but if I do it from CircleView class, it works (for example changing the color upon touch)
Here is my custom View class (CircleView.java):
public class CircleView extends View {
private int circleColor = Color.GREEN;
private Paint paint;
public CircleView(Context context) {
super(context);
init(context, null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
this.circleColor = setRandomColor();
invalidate();
break;
case MotionEvent.ACTION_DOWN:
this.circleColor = setRandomColor();
invalidate();
break;
}
return super.onTouchEvent(event);
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint = new Paint();
paint.setAntiAlias(true);
}
public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
invalidate();
}
public int setRandomColor() {
Random random = new Random();
int randomColor = Color.argb(255, random.nextInt(), random.nextInt(), random.nextInt());
return randomColor;
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...
//someXvalue, someYvalue, someRadius are being set here
//...
paint.setColor(circleColor);
canvas.drawCircle(someXvalue, someYvalue, someRadius, paint);
}
}
And here is my MainActivity.java class:
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener {
private GestureDetectorCompat mDetector;
CircleView circle;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat(this, this);
circle = new CircleView(this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
#Override
public boolean onDown(MotionEvent event) {
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent event) {
circle.setCircleColor(circle.setRandomColor(0));
circle.invalidate();
return true;
}
}
I am new to Android development, and Java as well. I realize it could be something with the Context, which is something I have not fully understood yet. Could also be something with the TouchEvents. I am sure that someone out there can see my mistake. Any help is appreciated.
your circle view is not a part of activity's layout , it's just a object in memory which has no link to your activity screen so solutions
1.) Either set circle as Activity's view
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDetector = new GestureDetectorCompat(this, this);
circle = new CircleView(this);
setContentView(circle);
}
2.) you can create your <yourpackagename.CircleView ...attributes .../> tag in your activity_main.xml and then use findViewById to initialize it in your activity.
1)If all you want to do with gestures is on tap, just implement an onClickListener on your View instead.
2)You aren't actually using the GestureDetector anywhere. The way it works is you set an onTouchListener for the view you want to get gestures on, and send the events to the gesture detector. You aren't ever sending data for any view to the detector, so it will never do anything.
3)Not a bug just an oddness- why circle.setColor(circle.setRandomColor())? I would expect a function named setXXX to actually set XXX, rather than having to do it yourself later. Not following that convention will work, but make debugging and maintenance hard.
Edit: Also what #Pavneet_Singh said- your circle isn't in your layout anywhere, so it won't be on screen.
i implemented a search text for my list,
Every list row item includes a text and image that i downloaded from server.
i alsways keeps two list, one is the original List of text and images and other one is the sorted Lists of text and image...
if my list containes only 4 items, so my app works well, however if my list containes 20 items and every image is 1MB and i need to keep two lists listImagesOriginal , image_array inside adapter ( = 40MB) i recieve a OutOfMemory Exception.
how can i reduce the memory consuption that i will not recive a OutOfMemory Exception?
thanks alot
how can i reduce the
private MyCustomAdapter adapter;
private List<String> text = new ArrayList<String>();
private List<Bitmap> listImages;
private List<String> textOriginal = new ArrayList<String>();
private List<Bitmap> listImagesOriginal =new ArrayList<Bitmap>();
adapter =new MyCustomAdapter(text,listImages);
ListView.setAdapter(adapter);
searchText= (EditText) findViewById(R.id.profile_page_search);
searchText.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
// Abstract Method of TextWatcher Interface.
textlength = searchText.getText().length();
adapter.deleteAllForSearch();
for (int i = 0; i < textOriginal.size(); i++)
{
if(textOriginal.get(i).contains(
searchText.getText().toString().trim()))
{
adapter.addObjectForSearch(textOriginal.get(i), listImagesOriginal.get(i));
}
}
}
public void beforeTextChanged(CharSequence s,
int start, int count, int after)
{
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence s,
int start, int before, int count)
{
}
});
class MyCustomAdapter extends BaseAdapter{
public List<String> text_array = new ArrayList<String>();
public List<Bitmap> image_array = new ArrayList<Bitmap>();
public int getCount(){
return text_array.size();
}
MyCustomAdapter(List<String> text, List<Bitmap>)
{
text_array = text;
image_array = image;
}
public long getItemId(int position){
return position;
}
public String getItem(int position){
return null;
}
public View getView(final int position, View convertView, ViewGroup parent) {
//my implementation
}
public void addObjectForSearch(String text, Bitmap bitmap) {
text_array.add(text);
image_array.add(bitmap);
notifyDataSetChanged();
}
40MB is way too much for android. Every phone has a per app memory limit, 40MB is higher than even most high end phones use. You need to implement disk and/or memory caching of your images.
You need to use a cache and/or store them into persistent memory (DB, filesystem, etc), as you don't want all those bitmaps loaded into memory at the same time, especially if you don't see them all at the same time. Many older devices have VM heap sizes around 16-24MB, and you need to be able to stay within a reasonable amount of memory usage.
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html