How Can I Some ImageView Add to relativeLayout - android

I would like to add some ImageViews to a RelativeLayout view.
The code that I'm using is as follows:
Thread thread = new Thread(new Runnable() {
ArrayList<ImageView> icons = new ArrayList<ImageView>();
#Override
public void run() {
for (int i = 0; i < 20; i++) {
ImageView imageView1 = new ImageView(G.context);
imageView1.setImageResource(R.drawable.music_icon);
imageView1.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
imageView1.getLayoutParams().width = (int) convertDpToPixel(20);
imageView1.getLayoutParams().height = (int) convertDpToPixel(20);
icons.add(imageView1);
Log.i("LOG", "Icons Size: " + icons.size());
Log.i("LOG", "I: " + i);
relativeLayout.addView(icons.get(i));
icons.get(i).startAnimation(animationMusic);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread.start();
The first time the loop runs fine, but the second time there's an error in the line:
relativeLayout.addView(icons.get(i));
Where is the problem?

One major problem is manipulating the view (e.g. adding a View) from a background thread. You can get similar async behavior by making use of Android's AsyncTask objects and do any UI manipulation from the onPostExecute method.
Without know more about what you're doing, it's hard to find a solution that will work for you. I was mainly pointing out a primary issue with your code.
Here is an attempt to rewrite your code in a way that might work better in an Android environment:
public void addImageViews() {
for(int i = 0; i < 20; i++) {
asyncAdd(i, G.context);
}
}
protected void asyncAdd(final int index, final Context c) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(3000 * index);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
relativeLayout.addView(generateImageView(c));
}
}.execute();
}
protected ImageView generateImageView(Context c) {
ImageView imageView1 = new ImageView(c);
imageView1.setImageResource(R.drawable.music_icon);
imageView1.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
imageView1.getLayoutParams().width = (int) convertDpToPixel(20);
imageView1.getLayoutParams().height = (int) convertDpToPixel(20);
return imageView1;
}

Related

Android get Images from Picasso to Bitmap Array

I want to get a Bitmap[] from my String[] with links. But this doesn't work as I want. I have this Method:
private Bitmap[] getBitmaps(String[] images){
ArrayList<Bitmap> temp = new ArrayList<>();
for(int i = 0; i < images.length; i++){
ImageView img = new ImageView(getContext());
FrameLayout.LayoutParams x = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
img.setLayoutParams(x);
Picasso.with(getContext()).load(MainPostAdapter.USER_URL+images[i]+".png").into(img, new Callback() {
#Override
public void onSuccess() {
temp.add(BitmapRes.drawableToBitmap(img.getDrawable()));
movableBackgroundContainer.removeView(img);
}
#Override
public void onError() {
}
});
movableBackgroundContainer.addView(img);
}
return temp.toArray(new Bitmap[temp.size()]);
}
The problem is I get a null Array because it adds the Bitmap to the list after the onSuccess function. How can I now wait until all onSuccess added the bitmaps and then return?
The get() function of Picasso does what you're looking for. It downloads a Bitmap rather than load an image into an ImageView. Note that Picasso's get() method cannot be called on the main thread. My example uses an AsyncTask to download images on a separate thread.
String[] images = new String[] {"http://path.to.image1.jpg", "http://path.to.image2.jpg"};
new AsyncTask<String[], Void, List<Bitmap>>() {
#Override
protected List<Bitmap> doInBackground(String[]... params) {
try {
List<Bitmap> bitmaps = new ArrayList<Bitmap>();
for (int i = 0; i < params[0].length; ++i) {
bitmaps.add(Picasso.with(getActivity()).load(params[0][i]).get());
}
return bitmaps;
} catch (IOException e) {
return null;
}
}
#Override
public void onPostExecute(List<Bitmap> bitmaps) {
if (bitmaps != null) {
// Do stuff with your loaded bitmaps
}
}
}.execute(images);
You could increase an integer every time on success until the integer equals to the images.lengh(). You could check this with a loop. And in the loop is an if clause within the return.
For example
int currentSuccess = 0;
In the loop:
#Override
public void onSuccess() {
temp.add(BitmapRes.drawableToBitmap(img.getDrawable()));
movableBackgroundContainer.removeView(img);
currentSuccess++;
}
And for the return:
while(true){
if(currentSuccess == images.length){
return temp.toArray(new Bitmap[temp.size()]);
}
}
Hope that helps.

Execute Thread in every Viewpager item

I have two images, in single viewpager item. When i am clicking on any image it display a line, simple line.
I am growing this line using thread, line is percentage of vote that are given to particular image, based on percentage lines are drawn on both image after click
But problem is that if i click on one image single line is drawn on that particular image, and every other viewpager items no line is drawn on click
I want two lines after click on any image, so what to do
ivImageOne.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
id = arraylist.get(position).get("user_id1");
feed_id = arraylist.get(position).get("feed_id");
Log.e("feeeeeee", feed_id);
View tempView = (View) v.getTag(R.integer.btnminusview);
Integer pos = (Integer) v.getTag(R.integer.btnminuspos);
ivRightTick = (ImageView) tempView.findViewById(R.id.ivRightTick);
ivLeftTick = (ImageView) tempView.findViewById(R.id.ivLeftTick);
ivLeftTick.setVisibility(View.GONE);
ivRightTick.setVisibility(View.VISIBLE);
vOne = (View) tempView.findViewById(R.id.vOne);
vTwo = (View) tempView.findViewById(R.id.vTwo);
mThread = new Thread() {
#Override
public void run() {
while (pStatus < pcount1) {
pStatus += 10;
handler.post(new Runnable() {
#Override
public void run() {
android.view.ViewGroup.LayoutParams params = vOne.getLayoutParams();
params.height = pStatus;
params.width = 10;
Log.d("pppppppppppppp", params.height + "");
vOne.setLayoutParams(params);
// vOne.setLayoutParams(new WindowManager.LayoutParams(1,pStatus));
if (pStatus == pcount1) {
stopThread(mThread);
}
}
});
try {
Thread.sleep(19); //thread will take approx 2.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
mThread2 = new Thread() {
#Override
public void run() {
while (pStatus2 > MIN_VALUE) {
pStatus2 += 10;
handler2.post(new Runnable() {
#Override
public void run() {
android.view.ViewGroup.LayoutParams params = vTwo.getLayoutParams();
params.height = pStatus;
params.width = 10;
Log.d("pppppppppppppp", params.height + "");
vTwo.setLayoutParams(params);
// vOne.setLayoutParams(new WindowManager.LayoutParams(1,pStatus));
if (pStatus2 == pcount2) {
stopThread(mThread2);
}
}
});
try {
Thread.sleep(19); //thread will take approx 2.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
mThread.start();
mThread2.start();
}
});
ivFeedImageTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// giveVote(2);
id = arraylist.get(position).get("user_id2");
feed_id = arraylist.get(position).get("feed_id");
View tempView = (View) v.getTag(R.integer.btnminusview);
Integer pos = (Integer) v.getTag(R.integer.btnminuspos);
ivLeftTick = (ImageView) tempView.findViewById(R.id.ivLeftTick);
ivRightTick = (ImageView) tempView.findViewById(R.id.ivRightTick);
ivLeftTick.setVisibility(View.VISIBLE);
ivRightTick.setVisibility(View.GONE);
vOne = (View) tempView.findViewById(R.id.vOne);
vTwo = (View) tempView.findViewById(R.id.vTwo);
mThread = new Thread() {
#Override
public void run() {
while (pStatus < pcount2) {
pStatus += 10;
handler.post(new Runnable() {
#Override
public void run() {
android.view.ViewGroup.LayoutParams params = vTwo.getLayoutParams();
params.height = pStatus;
params.width = 10;
Log.d("pppppppppppppp", params.height + "");
vTwo.setLayoutParams(params);
// vOne.setLayoutParams(new WindowManager.LayoutParams(1,pStatus));
if (pStatus == pcount2) {
stopThread(mThread);
}
}
});
try {
Thread.sleep(19); //thread will take approx 2.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
mThread2 = new Thread() {
#Override
public void run() {
while (pStatus2 > MIN_VALUE) {
pStatus2 += 10;
handler2.post(new Runnable() {
#Override
public void run() {
android.view.ViewGroup.LayoutParams params = vOne.getLayoutParams();
params.height = pStatus;
params.width = 10;
Log.d("pppppppppppppp", params.height + "");
vOne.setLayoutParams(params);
// vOne.setLayoutParams(new WindowManager.LayoutParams(1,pStatus));
if (pStatus2 == pcount1) {
stopThread(mThread2);
}
}
});
try {
Thread.sleep(19); //thread will take approx 2.5 seconds to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
mThread2.start();
mThread.start();
}
});
Here's how you handle your immediate problem:
Code a method on your activity/fragment that starts the animation for the two lines. Then set up two identical OnClickListeners, one on each image, that simply call the animation method.
What I'm more concerned about is your use of Threads for the animation. That is not the Android way. You should use an animator to make the visual change to your view. The code could be as simple as:
float pct = ... // ratio of votes to total votes, from 0.0 to 1.0
vOne.setScaleX(0F);
vOne.animate().setDuration(150).scaleXBy(pct).start();
Please look at some of the animation tutorials on the Android Developers site and elsewhere on the web.

Android program stops at doInBackground and doesn't come to onPostExecute

My program crashs after doInBackground and doesn't come to onPostExecute.
My activity code's related parts are like this:
public static class News {
private String title;
private String content;
private Bitmap image;
public News(String nTitle, String nContent, Bitmap nImage){
title = nTitle;
content = nContent;
image = nImage;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
final AsyncTask task = new DatabaseConnection(this, Method.GET_ALL_NEWS).execute();
try {
task.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public final void fillListView(List<News> news){
recentNews = news;
if(recentNews != null && !recentNews.isEmpty()){
((ListView)findViewById(R.id.lvNews)).setOnItemClickListener(this);
final int size = recentNews.size();
final String newsTitles[] = new String[size];
for(int i=0; i<size; ++i)
newsTitles[i] = recentNews.get(i).title;
((ListView)findViewById(R.id.lvNews)).setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, newsTitles));
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final News selectedNews = recentNews.get(position);
startActivity(new Intent(this, ANewsActivity.class)
.putExtra("title", selectedNews.title)
.putExtra("content", selectedNews.content)
.putExtra("image", BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)));
}
My AsyncTask code's related parts are like this:
public DatabaseConnection(Context nContext, Method nMethod){
method = nMethod;
context = nContext;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(context.getString(R.string.database_connection_wait_message));
progressDialog.setTitle(R.string.database_connection_wait_title);
progressDialog.show();
}
#SuppressWarnings("incomplete-switch")
#Override
protected Void doInBackground(String... params) {
if(method != Method.NONE){
open();
try{
switch(method){
case GET_ALL_NEWS:
final ResultSet rs = conn.createStatement().executeQuery("select baslik, metin, resim from haberler");
news = new ArrayList<News>();
while(rs.next())
news.add(new News(rs.getString(1), rs.getString(2), BitmapFactory.decodeStream(rs.getBlob(3).getBinaryStream())));
break;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
}
return null;
}
#SuppressWarnings("incomplete-switch")
#Override
protected void onPostExecute(Void temp) {
if (progressDialog.isShowing()){
progressDialog.dismiss();
switch(method){
case GET_ALL_NEWS:
((NewsActivity)context).fillListView(news);
break;
}
method = Method.NONE;
}
}
I want UI thread waits until database operations finishes.
By the way there is no initialization problem at variables etc and database returns proper infos and my "news" variable is filled normally.
By the way again I realized it is WORKING on PHONE, STUCKS on EMULATOR interestingly (if I remove wait() method and its try-catch block on main thread code).
It's difficult to say what is crashing without the logcat output, but it would most likely be the main thread of the app because of the .wait() method you are calling in onCreate(). Your onCreate() cannot wait - it must initialize and exit, otherwise you are blocking the main thread of your app and defeating the purpose of the AsyncTask.

Series of AsyncTask does not go for execution instantaneously

My MainActivity has 2 views: TextView and a Button. On button click, I am running an AsyncTask which further creates 10 new AsyncTasks for network operations. Every new task creation is delayed by 1 sec. The code is:
public class MainActivity extends ActionBarActivity
{
TextView tv;
Button t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.textView1);
t = (Button) findViewById(R.id.toggleButton1);
t.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
getData();
}
});
}
void getData()
{
SuperNetworkAsyncTask s = new SuperNetworkAsyncTask();
s.execute("");
}
private class SuperNetworkAsyncTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls)
{
for(int i=0;i<10;i++)
{
{
nTask = new NetworkAsyncTask();
nTask.execute("");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return "";
}
#Override
protected void onPostExecute(String result)
{
}
}
private class NetworkAsyncTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls)
{
return String.valueOf(System.currentTimeMillis());
}
#Override
protected void onPostExecute(String result)
{
tv.setText(result);
}
}
}
I was expecting that the moment first NetworkAsyncTask execute method is called, it will start execution. But when I run it, I do not find any NetworkAsyncTask begin its execution until the control comes out of SuperNetworkAsyncTask. Is there any way to push the execution of NetworkAsyncTask thread as soon as execute method is called?
Some clarifications:
Why NetworkAsyncTask are created by SuperNetworkAsyncTask? Because If I create the NetworkAsyncTask in main thread, I get my UI freeze for some time.
Why making 10 object? The purpose of NetworkAsyncTask is to read data from a server at interval of 1 sec for n seconds, here n=10.
Part 2: Updates after doing some tests.
Observation 1:
As a fellow Brian shared a way to avoid creating AsyncTasks in nested way, I tried his code:
void getData() {
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
nTask = new NetworkAsyncTask();
nTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
}
This freezes my UI for few seconds and then the screen is updated in a fraction of second. It is quite surprising to me too.
Observation 2:
With java.lang.Thread, I experimented to make sure that 1) The threads should be executed right away when run() called. 2) The next task will be created only after previous task is finished.
Code:
public static void main(String[] args) {
myThread m;
for (int i=0;i<10;i++)
{
m=new myThread(String.valueOf(i));
m.start();
synchronized (m)
{
try {
m.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class myThread extends Thread
{
public String name = "";
public myThread(String n)
{
name = n;
}
public void run()
{
synchronized (this)
{
System.out.println(" Thread Name = " + name);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
notifyAll();
}
}
}
Output:
Thread Name = 0
Thread Name = 1
Thread Name = 2
Thread Name = 3
Thread Name = 4
Thread Name = 5
Thread Name = 6
Thread Name = 7
Thread Name = 8
Thread Name = 9
Based in this, I updated my NetworkAsyncTask & SuperNetworkAsyncTask as:
private class NetworkAsyncTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls)
{
synchronized (this)
{
return String.valueOf(System.currentTimeMillis());
}
}
#Override
protected void onPostExecute(String result)
{
synchronized (this)
{
tv.setText(result);
notifyAll();
}
}
}
private class SuperNetworkAsyncTask extends AsyncTask<String, Void, String>
{
#Override
protected String doInBackground(String... urls)
{
for(int i=0;i<10;i++)
{
nTask = new NetworkAsyncTask();
nTask.execute(url);
synchronized (nTask)
{
try {
nTask.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return "";
}
#Override
protected void onPostExecute(String result)
{
}
}
With this code the wait() keeps on waiting indefinitely.
Finally I replaced:
nTask.execute(url);
with
nTask.executeOnExecutor(THREAD_POOL_EXECUTOR, "");
This worked well as expected.
The UI will be updated only at onPostExecute(). See notes on AsyncTask
Click here! And Try to avoid 10 AysncTasks, it does not make any sense.
You don't need to use a "super async task" use a runnable and then create new async tasks in parallel
void getData() {
Runnable runnable = new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 10; i++) {
nTask = new NetworkAsyncTask();
nTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
new Thread(runnable).start();
}
Post honeycomb you can specify to run async tasks in parallel
An AsyncTask should be started in the UI thread, not on the one doInBackground runs on. You could call publishProgress after every sleep, and spawn each AsyncTask in the resulting calls to onProgressUpdate, which run on the UI thread.

Android loop update TextView

I am trying to create a loop that will update a TextView.
The idea is to create some sort of progress indicator, that will increment the
loading precentge.
This is what I have tried, but the result is that I see only the last update of the loop, so I get "100%" with no incremntation.
runOnUiThread(new Runnable() {
public void run() {
final TextView progesss = (TextView)findViewById(R.id.progress);
for(int k=1 ; k<=100; k++)
{
progesss.setText(String.valueOf(k) + "%");
try {
Thread.sleep(15);
} catch(InterruptedException e) {
}
}
}
});
Any ideas of how to achieve my goal?
Thanks!
Your Runnable blocks the UI thread when doing Thread.sleep. Instead of sleeping, you should post a new Runnable again. Try with something like this:
final Handler handler = new Handler();
handler.post( new Runnable(){
private int k = 0;
public void run() {
final TextView progess = (TextView)findViewById(R.id.progress);
progess.setText(String.valueOf(k) + "%");
k++;
if( k <= 100 )
{
// Here `this` refers to the anonymous `Runnable`
handler.postDelayed(this, 15);
}
}
});
That will give the UI thread a chance to run between each call, letting it do its stuff like handling input and drawing stuff on the screen.
You use background thread and UI Thread.
public class testAsync extends AsyncTask<Void, Integer, Voi>{
TextView progress; // You will set TextView referans
protected void doInBackground(){
for(int k=1 ; k<=100; k++)
{
try {
Thread.sleep(1000);
publishProgress(k);
} catch(InterruptedException e) {}
}
}
protected void onProgressUpdate(Integer.. values)
{
progress.setText(values[0]+");
}
}
}

Categories

Resources