изучаю Android (Java). Необходимо создать меню программно с иконками. Я посылаю запрос на сервер и мне сервер отдает Json строку, я в Java ее конвертирую в объект и работаю с ним. Картинка передается в виде URL ссылки на файл. Задача такая, создать меню из этого объекта вместе с иконками. Сами меню создать не проблема, проблема в том что иконки не подставляются.
Привожу укороченный код
package com.example.app;
public class MainActivity extends AppCompatActivity implements OnNavigationItemSelectedListener, AsyncInternetTasks.MainInterfaceFunctions {
TextView testTextStatus;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(R.string.empty_text);
setSupportActionBar(toolbar);
// Менюшка
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
testTextStatus = findViewById(R.id.textView);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Нет иконки
menu.add(R.id.main_group, 1, 5, "Тест1")
.setIcon(Drawable.createFromPath("http://www.test.ru/images/test_icon1.jpg"))
.setCheckable(true);
// Иконки нет
menu.add(R.id.main_group, 1, 5, "Тест2")
.setIcon(Drawable.createFromPath("http://www.test.ru/images/test_icon2.png"))
.setCheckable(true);
// Нет иконки
menu.add(R.id.main_group, 1, 5, "Тест3")
.setIcon(Drawable.createFromPath(getTempFile(getApplicationContext(), "http://www.test.ru/images/test_icon2.png"))).setCheckable(true);
// тут NULL
Log.d("myTag1", String.valueOf(Drawable.createFromPath(getTempFile(getApplicationContext(), "http://www.test.ru/images/test_icon2.png"))));
return super.onCreateOptionsMenu(menu);
}
private String getTempFile(Context context, String url) {
File file = null;
try {
String fileName = Uri.parse(url).getLastPathSegment();
file = File.createTempFile(fileName, null, context.getCacheDir());
} catch (IOException e) {
// Error while creating file
}
// файлы также есть
Log.d("myTag1", file.getPath());
return file.getPath();
}
}
Подскажите пожалуйста, что не так я делаю. Спасибо!
Drawable.createFromPath
- метод принимает путь к локальному файлу, а не сетевой адрес.
И, поскольку, сетевые вызовы в главном потоке запрещены - то загрузить их прямо в onCreateOptionsMenu
не выйдет.
Самым разумным вариантом будет предварительная загрузка нужных картинок в локальный кэш или (если они легковесные) сразу в память.
Valeriy, спасибо за совет по Glide, классная библиотека - она мне пригодится.
Woesss, спасибо за подсказку, я понял что не так было в моем коде и почему возвращался null
// тут NULL
Log.d("myTag1", String.valueOf(Drawable.createFromPath(getTempFile(getApplicationContext(), "http://www.test.ru/images/test_icon2.png"))));
я создавал пустой файл (как оказалась) в методе getTempFile, собственно поэтому иконка в менюшку не подставлялась.
Завел для этого отдельный класс. Он сохраняет в кеше и возвращает путь к изображению (я вот сейчас думаю в этом же классе реализовать сохранение пути к файлам в БД или вынести в отдельный класс? И стоило ли реализовывать это отдельным классом).
Ниже приведу код класса, если что - то не так - подскажите пожалуйста что можно улучшить.
package com.example.app.helpers;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
public class AsyncFilesTasks extends AsyncTask<Void, Void, String> {
private MainInterfaceFunctions callback;
private String folder, urlFilePath;
private Context context;
public AsyncFilesTasks(final MainInterfaceFunctions callback, Context context, String folder, String urlFilePath){
this.callback = callback;
this.context = context;
this.folder = folder;
this.urlFilePath = urlFilePath;
}
public interface MainInterfaceFunctions {
void afterTasksSaveFileToCashe(String filePatch);
void beforeTasksSaveFileToCashe();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if (callback != null)
callback.beforeTasksSaveFileToCashe();
}
@Override
protected String doInBackground(Void... voids) {
return getTempFile(context, urlFilePath);
}
@Override
public void onPostExecute(String filePatch) {
super.onPostExecute(filePatch);
if(callback!=null) {
callback.afterTasksSaveFileToCashe(filePatch);
}
}
private String getTempFile(Context context, String url_img) {
File file = null;
URL url = null;
try {
url = new URL(url_img);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
String fileName = Uri.parse(url_img).getLastPathSegment();
File folder = new File(context.getCacheDir(), this.folder);
if (!folder.exists()) {
if (!folder.mkdir()) {
Log.e("myTag1", "Cannot create a directory!");
} else {
folder.mkdirs();
}
}
file = File.createTempFile(fileName, null, folder);
Bitmap bitmap;
if (url != null) {
bitmap = BitmapFactory.decodeStream(url.openStream());
bitmap.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(file));
}
} catch (IOException e) {
// Error while creating file
}
return file.getPath();
}
}
вызывать вот так
AsyncFilesTasks AFT = new AsyncFilesTasks(this, getApplicationContext(), "/menu_icons/", "http://www.test.ru/local/images/test.png");
AFT.execute();
// в классе где выполняется объект класса AsyncFilesTasks необходимо переопределить эти методы, так как они будут вызваны до сохранения картинки и после сохранения
@Override
public void beforeTasksSaveFileToCashe() {
}
@Override
public void afterTasksSaveFileToCashe(String filePatch) {
Log.d("myTag1", filePatch);
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Делаю фильтр по нажатию на кнопку должно найти у item категорию которая совпадает с категорией на кнопку, эти элементы оставить а остальные...
задача состоит в том чтоб, создать кнопку onlineточнее когда любой пользователь/гость на сайте смотри любой пост, нужно чтоб статус автора был...
В браузерах на андроидах не работает выпадающие меню на сайтеJS код: