I have an unexpe`ted problem with my Android project. I have a real android device with ice_cream sandwich installed. My app was working fine during the development but after I added a class to the project, I got an error:
Installation error: INSTALL_FAILED_OLDER_SDK
The problem is that everything is good in the manifest file. The minSdkversion is 8.
Here is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zabolotnii.pavel.timer"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18 " />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="zabolotnii.pavel.timer.TimerActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I don't know, if there is any need to attach the new class ,but I didn't any changes to other code that should led to this error:
package zabolotnii.pavel.timer;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.*;
import android.widget.*;
import java.io.File;
import java.io.FilenameFilter;
import java.util.*;
public class OpenFileDialog extends AlertDialog.Builder {
private String currentPath = Environment.getExternalStorageDirectory().getPath();
private List<File> files = new ArrayList<File>();
private TextView title;
private ListView listView;
private FilenameFilter filenameFilter;
private int selectedIndex = -1;
private OpenDialogListener listener;
private Drawable folderIcon;
private Drawable fileIcon;
private String accessDeniedMessage;
public interface OpenDialogListener {
public void OnSelectedFile(String fileName);
}
private class FileAdapter extends ArrayAdapter<File> {
public FileAdapter(Context context, List<File> files) {
super(context, android.R.layout.simple_list_item_1, files);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView view = (TextView) super.getView(position, convertView, parent);
File file = getItem(position);
if (view != null) {
view.setText(file.getName());
if (file.isDirectory()) {
setDrawable(view, folderIcon);
} else {
setDrawable(view, fileIcon);
if (selectedIndex == position)
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.holo_blue_dark));
else
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.transparent));
}
}
return view;
}
private void setDrawable(TextView view, Drawable drawable) {
if (view != null) {
if (drawable != null) {
drawable.setBounds(0, 0, 60, 60);
view.setCompoundDrawables(drawable, null, null, null);
} else {
view.setCompoundDrawables(null, null, null, null);
}
}
}
}
public OpenFileDialog(Context context) {
super(context);
title = createTitle(context);
changeTitle();
LinearLayout linearLayout = createMainLayout(context);
linearLayout.addView(createBackItem(context));
listView = createListView(context);
linearLayout.addView(listView);
setCustomTitle(title).setView(linearLayout)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (selectedIndex > -1 && listener != null) {
listener.OnSelectedFile(listView.getItemAtPosition(selectedIndex).toString());
}
}
}).setNegativeButton(android.R.string.cancel, null);
}
#Override
public AlertDialog show() {
files.addAll(getFiles(currentPath));
listView.setAdapter(new FileAdapter(getContext(), files));
return super.show();
}
public OpenFileDialog setFilter(final String filter) {
filenameFilter = new FilenameFilter() {
#Override
public boolean accept(File file, String fileName) {
File tempFile = new File(String.format("%s/%s", file.getPath(), fileName));
if (tempFile.isFile())
return tempFile.getName().matches(filter);
return true;
}
};
return this;
}
public OpenFileDialog setOpenDialogListener(OpenDialogListener listener) {
this.listener = listener;
return this;
}
public OpenFileDialog setFolderIcon(Drawable drawable) {
this.folderIcon = drawable;
return this;
}
public OpenFileDialog setFileIcon(Drawable drawable) {
this.fileIcon = drawable;
return this;
}
public OpenFileDialog setAccessDeniedMessage(String message) {
this.accessDeniedMessage = message;
return this;
}
private static Display getDefaultDisplay(Context context) {
return ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
}
private static Point getScreenSize(Context context) {
Point screeSize = new Point();
getDefaultDisplay(context).getSize(screeSize);
return screeSize;
}
private static int getLinearLayoutMinHeight(Context context) {
return getScreenSize(context).y;
}
private LinearLayout createMainLayout(Context context) {
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setMinimumHeight(getLinearLayoutMinHeight(context));
return linearLayout;
}
private int getItemHeight(Context context) {
TypedValue value = new TypedValue();
DisplayMetrics metrics = new DisplayMetrics();
context.getTheme().resolveAttribute(android.R.attr.listPreferredItemHeightSmall, value, true);
getDefaultDisplay(context).getMetrics(metrics);
return (int) TypedValue.complexToDimension(value.data, metrics);
}
private TextView createTextView(Context context, int style) {
TextView textView = new TextView(context);
textView.setTextAppearance(context, style);
int itemHeight = getItemHeight(context);
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
textView.setMinHeight(itemHeight);
textView.setGravity(Gravity.CENTER_VERTICAL);
textView.setPadding(15, 0, 0, 0);
return textView;
}
private TextView createTitle(Context context) {
TextView textView = createTextView(context, android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
return textView;
}
private TextView createBackItem(Context context) {
TextView textView = createTextView(context, android.R.style.TextAppearance_DeviceDefault_Small);
Drawable drawable = getContext().getResources().getDrawable(android.R.drawable.ic_menu_directions);
drawable.setBounds(0, 0, 60, 60);
textView.setCompoundDrawables(drawable, null, null, null);
textView.setLayoutParams(
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
File file = new File(currentPath);
File parentDirectory = file.getParentFile();
if (parentDirectory != null) {
currentPath = parentDirectory.getPath();
RebuildFiles(((FileAdapter) listView.getAdapter()));
}
}
});
return textView;
}
public int getTextWidth(String text, Paint paint) {
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
return bounds.left + bounds.width() + 80;
}
private void changeTitle() {
String titleText = currentPath;
int screenWidth = getScreenSize(getContext()).x;
int maxWidth = (int) (screenWidth * 0.99);
if (getTextWidth(titleText, title.getPaint()) > maxWidth) {
while (getTextWidth("..." + titleText, title.getPaint()) > maxWidth) {
int start = titleText.indexOf("/", 2);
if (start > 0)
titleText = titleText.substring(start);
else
titleText = titleText.substring(2);
}
title.setText("..." + titleText);
} else {
title.setText(titleText);
}
}
private List<File> getFiles(String directoryPath) {
File directory = new File(directoryPath);
List<File> fileList = Arrays.asList(directory.listFiles(filenameFilter));
Collections.sort(fileList, new Comparator<File>() {
#Override
public int compare(File file, File file2) {
if (file.isDirectory() && file2.isFile())
return -1;
else if (file.isFile() && file2.isDirectory())
return 1;
else
return file.getPath().compareTo(file2.getPath());
}
});
return fileList;
}
private void RebuildFiles(ArrayAdapter<File> adapter) {
try {
List<File> fileList = getFiles(currentPath);
files.clear();
selectedIndex = -1;
files.addAll(fileList);
adapter.notifyDataSetChanged();
changeTitle();
} catch (NullPointerException e) {
String message = getContext().getResources().getString(android.R.string.unknownName);
if (!accessDeniedMessage.equals(""))
message = accessDeniedMessage;
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
}
}
private ListView createListView(Context context) {
ListView listView = new ListView(context);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int index, long l) {
final ArrayAdapter<File> adapter = (FileAdapter) adapterView.getAdapter();
File file = adapter.getItem(index);
if (file.isDirectory()) {
currentPath = file.getPath();
RebuildFiles(adapter);
} else {
if (index != selectedIndex)
selectedIndex = index;
else
selectedIndex = -1;
adapter.notifyDataSetChanged();
}
}
});
return listView;
}
}
Remove the space from your targetSdkVersion value. Change
android:targetSdkVersion="18 "
to
android:targetSdkVersion="18"
The app installer has different logic (source) for versions given as strings such as "18 " as opposed to versions given as integers such as "18". You really need the value to be there as an integer.
Related
How to use holder.todoCheckbox.setChecked (todoBool);
I have a recycler view that contains 3 view holders.
I have got a MainActivity, HeaderFooterAdapter, SimpleItamAdapter.
I have the logic when I click on a checkbox that the list will filter. In the setOnCheckedChangeListener I set the variables todoBool, doneBool, projectBool to the new truth values.
Then I would like to set the checkboxes to true or false depending on these values.
The problem occurs on this line of code
holder.todoCheckbox.setChecked(todoBool);
This causes a crash in the app.
public void onBindHeaderItemViewHolder(#NonNull HeaderViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
//This following 3 lines causes error. how to manage this?
holder.todoCheckbox.setChecked(todoBool);
holder.doneCheckbox.setChecked(doneBool);
holder.projektCheckbox.setChecked(projectBool);
holder.todoCheckbox.setOnCheckedChangeListener(…); //here i set to Bools
holder.doneCheckbox.setOnCheckedChangeListener(…);
holder.projektCheckbox.setOnCheckedChangeListener(…);
}
I tried that. Also causes crash in the app.
holder.todoCheckbox.setChecked(false);
holder.doneCheckbox.setChecked(false);
holder.projektCheckbox.setChecked(false);
What do i do wrong?
I pushed everythink here. The "localBranch" is the not working one. The "devMaster" works. https://github.com/SaschaGolod/T09b.10-Exercise-AddViewModelToAddTaskActivity
Many thanks if someone can help me here
Here is my whole adapter class:
package com.example.android.todolist.adapters;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import com.example.android.todolist.R;
import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils;
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import static com.example.android.todolist.MainActivity.onItemClickedDefault;
import static com.example.android.todolist.MainActivity.onItemClickedDone;
import static com.example.android.todolist.MainActivity.onItemClickedProject;
import static com.example.android.todolist.MainActivity.onItemClickedTodo;
public class DemoHeaderFooterAdapter
extends AbstractHeaderFooterWrapperAdapter<DemoHeaderFooterAdapter.HeaderViewHolder, DemoHeaderFooterAdapter.FooterViewHolder>
implements View.OnClickListener {
private static final String TAG = "DemoHeaderFooterAdapter";
private OnListItemClickMessageListener mOnItemClickListener;
private Context mContext;
private boolean todoBool = false;
private boolean doneBool = false;
private boolean projectBool = false;
static class HeaderViewHolder extends RecyclerView.ViewHolder {
private CheckBox todoCheckbox;
private CheckBox doneCheckbox;
private CheckBox projektCheckbox;
HeaderViewHolder(View itemView) {
super(itemView);
todoCheckbox = itemView.findViewById(R.id.todoCheckboxID);
doneCheckbox = itemView.findViewById(R.id.doneCheckboxID);
projektCheckbox = itemView.findViewById(R.id.projektCheckboxID);
Log.i(TAG, "onCreate finished");
}
}
static class FooterViewHolder extends RecyclerView.ViewHolder {
FooterViewHolder(View itemView) {
super(itemView);
}
}
public DemoHeaderFooterAdapter(RecyclerView.Adapter adapter, OnListItemClickMessageListener clickListener, Context mContext) {
Log.i(TAG, "DemoHeaderFooterAdapter");
setAdapter(adapter);
mOnItemClickListener = clickListener;
this.mContext = mContext;
}
#Override
public int getHeaderItemCount() {
return 1;
}
#Override
public int getFooterItemCount() {
return 1;
}
#NonNull
#Override
public HeaderViewHolder onCreateHeaderItemViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.i(TAG, "HeaderViewHolder");
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_item, parent, false);
HeaderViewHolder vh = new HeaderViewHolder(v);
if (mOnItemClickListener != null) {
vh.itemView.setOnClickListener(this);
}
return vh;
}
#NonNull
#Override
public FooterViewHolder onCreateFooterItemViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.footer_item, parent, false);
FooterViewHolder vh = new FooterViewHolder(v);
if (mOnItemClickListener != null) {
vh.itemView.setOnClickListener(this);
}
return vh;
}
#Override
public void onClick(#NonNull View v) {
RecyclerView rv = RecyclerViewAdapterUtils.getParentRecyclerView(v);
RecyclerView.ViewHolder vh = rv.findContainingViewHolder(v);
int rootPosition = vh.getAdapterPosition();
if (rootPosition == RecyclerView.NO_POSITION) {
return;
}
// need to determine adapter local position like this:
RecyclerView.Adapter rootAdapter = rv.getAdapter();
int localPosition = WrapperAdapterUtils.unwrapPosition(rootAdapter, this, rootPosition);
// get segment
long segmentedPosition = getSegmentedPosition(localPosition);
int segment = extractSegmentPart(segmentedPosition);
int offset = extractSegmentOffsetPart(segmentedPosition);
String message;
if (segment == SEGMENT_TYPE_HEADER) {
message = "CLICKED: Header item " + offset;
} else if (segment == SEGMENT_TYPE_FOOTER) {
message = "CLICKED: Footer item " + offset;
} else {
throw new IllegalStateException("Something wrong.");
}
mOnItemClickListener.onItemClicked(message);
}
// --------------------------------------------
// [ OPTIONAL ]
// Set full-span for Grid layout and Staggered Grid layout
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
setupFullSpanForGridLayoutManager(recyclerView);
}
#Override
public void onBindHeaderItemViewHolder(#NonNull HeaderViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
//Maybe here is the mistake?
//Reload State of SharedPreferences
//This following 3 lines causes error :| how to manage this?
holder.todoCheckbox.setChecked(false);
holder.doneCheckbox.setChecked(false);
holder.projektCheckbox.setChecked(false);
holder.todoCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = false;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDefault);
}else{
todoBool = true;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedTodo);
}
}
});
holder.doneCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = false;
doneBool = true;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDone);
}else{
todoBool = false;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedDefault);
}
}
});
holder.projektCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
todoBool = true;
doneBool = false;
projectBool = true;
mOnItemClickListener.onItemClicked(onItemClickedProject);
}else{
todoBool = true;
doneBool = false;
projectBool = false;
mOnItemClickListener.onItemClicked(onItemClickedTodo);
}
}
});
}
#Override
public void onBindFooterItemViewHolder(#NonNull FooterViewHolder holder, int localPosition) {
applyFullSpanForStaggeredGridLayoutManager(holder);
}
// Filling span for GridLayoutManager
private void setupFullSpanForGridLayoutManager(RecyclerView recyclerView) {
RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
if (!(lm instanceof GridLayoutManager)) {
return;
}
final GridLayoutManager glm = (GridLayoutManager) lm;
final GridLayoutManager.SpanSizeLookup origSizeLookup = glm.getSpanSizeLookup();
final int spanCount = glm.getSpanCount();
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
final long segmentedPosition = getSegmentedPosition(position);
final int segment = extractSegmentPart(segmentedPosition);
final int offset = extractSegmentOffsetPart(segmentedPosition);
if (segment == SEGMENT_TYPE_NORMAL) {
return origSizeLookup.getSpanSize(offset);
} else {
return spanCount; // header or footer
}
}
});
}
private void applyFullSpanForStaggeredGridLayoutManager(RecyclerView.ViewHolder holder) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
// Filling span for StaggeredGridLayoutManager
if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
((StaggeredGridLayoutManager.LayoutParams) lp).setFullSpan(true);
}
}
// --------------------------------------------
}
-----------Edit 3----------------
public void notifyTaskEntrysChanged(String message){
switch (message) {
//Here set Booleans
}
filteredTaskEntries.clear();
//Now fill the filteredTaskEntries with new TaskEntries depending on the bools
Log.d(TAG, "notifyDataSetChanged next Step");
notifyDataSetChanged(); //Error 1. Line in Logcat
}
------------Edit2-----------------
In the MainActifity i handle the clicks like this:
#Override
public void onItemClicked(String message) {
switch (message) {
case onItemClickedTodo:
Log.d(TAG, "onItemClickedTriggerd: TodoChecked true");
TodoChecked = true;
DoneChecked = false;
ProjectChecked = false;
break;
case onItemClickedDone:
TodoChecked = false;
DoneChecked = true;
ProjectChecked = false;
break;
case onItemClickedProject:
ProjectChecked = true;
TodoChecked = true;
DoneChecked = false;
break;
default:
ProjectChecked = false;
TodoChecked = false;
DoneChecked = false;
break;
}
saveStateOfButtons();
Log.d(TAG, "mFilteringAdapter.notifyTaskEntrysChanged(message)");
mFilteringAdapter.notifyTaskEntrysChanged(message); //Error 2. Line in Logcat
}
The 3. Line Error is this code:
mOnItemClickListener.onItemClicked(onItemClickedDefault);
------------Edit1-----------------
Here is the Log.
[...]
D/DemoHeaderFooterAdapter: ----------------------------------------------------
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/DemoHeaderFooterAdapter: TodoSetOnCheckedChangeListener triggerd
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/MainActivity: onItemClickedTriggerd: TodoChecked true
03-22 19:50:49.267 13331-13331/com.example.android.todoDB D/MainActivity: saveStateButtons
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/MainActivity: mFilteringAdapter.notifyTaskEntrysChanged(message)
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/SimpleDemoItemAdapter: notifyTaskEntrysChanged finished
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/SimpleDemoItemAdapter: notifyDataSetChanged next Step
03-22 19:50:49.275 13331-13331/com.example.android.todoDB D/AndroidRuntime: Shutting down VM
03-22 19:50:49.277 13331-13331/com.example.android.todoDB E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.todoDB, PID: 13331
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{e9fff59 VFED..... .F....ID 0,0-480,680 #7f090090 app:id/recycler_view}, adapter:com.example.android.todolist.adapters.DemoHeaderFooterAdapter#1c3071e, layout:androidx.recyclerview.widget.LinearLayoutManager#b695bff, context:com.example.android.todolist.MainActivity#755b94c
at androidx.recyclerview.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2880)
at [...]
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11997)
at androidx.recyclerview.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7070)
at com.example.android.todolist.adapters.SimpleDemoItemAdapter.notifyTaskEntrysChanged(SimpleDemoItemAdapter.java:287)
I'm new to coding. I'm trying to implement a SearchView Widget that should update a GridView, but it doesn't work. When I type something in the search field nothing happens. Nothing happens if I tap on the search button neither. Could you please help me?
This is the MainActivity:
public class MainActivity extends AppCompatActivity {
private static Context mainContext;
private FragmentDataSaver mDataSaver;
private static final String DATA_SAVER_TAG = "DATA_SAVER";
private View mDecorView;
public ArrayList<Movies> mMovies;
WallAdapter wallAdapter;
GridView gridView;
public static Context getContext(){
return mainContext;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDecorView = getWindow().getDecorView();
mainContext = getApplicationContext();
setContentView(R.layout.activity_main);
Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
FragmentManager fm = getSupportFragmentManager();
mDataSaver = (FragmentDataSaver)fm.findFragmentByTag(DATA_SAVER_TAG);
if(mDataSaver == null){
mDataSaver = new FragmentDataSaver();
fm.beginTransaction().add(mDataSaver, DATA_SAVER_TAG).commit();
mMovies = DatabaseProva.creaDatabaseProva();
mDataSaver.setData(mMovies);
} else {
mMovies = mDataSaver.getData();
}
gridView = (GridView)findViewById(R.id.gridview_layout);
/*if(savedInstanceState == null){
mMovies = DatabaseProva.creaDatabaseProva();
} else {
mMovies = savedInstanceState.getParcelableArrayList("tempMovies");
}*/
wallAdapter = new WallAdapter(this, mMovies);
gridView.setAdapter(wallAdapter);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//use the query to search your data somehow
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.toolbar_menu, menu);
MenuItem searchMenu = menu.findItem(R.id.search_view);
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
android.widget.SearchView searchView = (android.widget.SearchView) searchMenu.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
wallAdapter.getFilter().filter(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
mDecorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
}
/*#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("tempMovies", wallAdapter.getItems());
}*/
The adapter (WallAdapter):
public class WallAdapter extends ArrayAdapter<Movies> implements Filterable{
private ArrayList<Movies> tempMovies = new ArrayList<Movies>();
public WallAdapter(Context context, ArrayList movies) {
super(context, 0, movies);
setItems(movies);
}
public ArrayList<Movies> getMovies() {
return tempMovies;
}
public void setItems(ArrayList<Movies> movies) {
this.tempMovies = movies;
}
public ArrayList<Movies> getItems() {
return tempMovies;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_layout, parent, false);
holder = new ViewHolder();
holder.mImage = (ImageView) convertView.findViewById(R.id.item_view);
holder.mImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Movies currentMovie = getItem(position);
holder.mImage.setImageBitmap(currentMovie.getImage());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getContext(), SchedaFilm.class);
intent.putExtra("titolo", currentMovie.getTitolo());
intent.putExtra("locandina", currentMovie.getIdLocandina());
intent.putExtra("trama", currentMovie.getTrama());
intent.putExtra("regia", currentMovie.getRegia());
intent.putExtra("anno", currentMovie.getAnno());
intent.putExtra("genere", currentMovie.getGenere());
getContext().startActivity(intent);
}
});
return convertView;
}
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
ArrayList<Movies> tempList = new ArrayList<>();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if(constraint != null || constraint.length() == 0) {
// No filter implemented we return all the list
filterResults.values = tempMovies;
filterResults.count = tempMovies.size();
} else {
for(Movies m : tempMovies){
if(m.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
tempList.add(m);
}
}
filterResults.values = tempList;
filterResults.count = tempList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.count == 0){
notifyDataSetInvalidated();
} else {
tempMovies = (ArrayList<Movies>) results.values;
notifyDataSetChanged();
}
}
};
#NonNull
#Override
public Filter getFilter() {
return filter;
}
static class ViewHolder{
private ImageView mImage;
public Context getContext(){
return mImage.getContext();
}
}
My manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="arca.mitty.com.arcagridview"
xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="android.intent.action.SEARCH" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".SchedaFilm"
android:parentActivityName=".MainActivity">
</activity>
</application>
</manifest>
The Searchable xml file:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_label"
android:hint="#string/search_hint" >
</searchable>
This is the Movie class:
public class Movies implements Parcelable{
private String mTitolo;
private String mGenere;
private Bitmap mLocandina;
private Bitmap mLocandinaBig;
private int mAnno;
private int mIdLocandina;
private String mTrama = "Seduto sulla panchina ad un bus-stop di Savannah, " +
"Forrest Gump ricorda la sua infanzia di bimbo con problemi mentali e fisici. " +
"Solo la mamma lo accetta per quello che è, e solo la piccola Jenny Curran lo fa sedere accanto a sé sull'autobus della scuola. " +
"Sarà lei a incitarlo, per fuggire a tre compagnetti violenti, a correre, liberando così le gambe dalla protesi. " +
"Attraverso trent'anni di storia americana vista con gli occhi della semplicità e dell'innocenza, Forrest diventa un campione universitario di football, " +
"mentre è sempre più innamorato di Jenny che però lo considera un fratello. Assiste ai disordini razziali in Alabama ed incontra Kennedy poco prima dell'assassinio. " +
"Si arruola quindi nell'esercito, dove fa amicizia con il nero Bubba, un pescatore di gamberi che gli comunica la sua passione. " +
"Dopo un fugace incontro con Jenny che canta a Memphis, Gump va a combattere in Vietnam.";
private String mRegia = "Bino Cicogna";
//Constructor
public Movies (String titolo, String genere, int locandina, int anno){
mTitolo = titolo;
mGenere = genere;
mIdLocandina = locandina;
mLocandina = decodeSampledBitmapFromResource(MainActivity.getContext().getResources(), locandina, 90, 135);
mAnno = anno;
}
protected Movies(Parcel in) {
mTitolo = in.readString();
mGenere = in.readString();
mLocandina = in.readParcelable(Bitmap.class.getClassLoader());
mAnno = in.readInt();
}
public static final Creator<Movies> CREATOR = new Creator<Movies>() {
#Override
public Movies createFromParcel(Parcel in) {
return new Movies(in);
}
#Override
public Movies[] newArray(int size) {
return new Movies[size];
}
};
public String getTitolo() {
return mTitolo;
}
public String getGenere() {
return mGenere;
}
public int getIdLocandina(){
return mIdLocandina;
}
public Bitmap getImage() {
return mLocandina;
}
public int getAnno() {
return mAnno;
}
public String getTrama(){
return mTrama;
}
public String getRegia(){
return mRegia;
}
public String toString(){
String s = "";
s = getTitolo() + " " + getGenere() + " " + getRegia() + " " + getAnno();
return s;
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mTitolo);
dest.writeString(mGenere);
dest.writeParcelable(mLocandina, flags);
dest.writeInt(mAnno);
}
}
In your filter, you are doing this:
if (m.toString().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempList.add(m);
}
Make sure m.toString() returns value that actually contains movie's name, if it doesn't that condition will always be false and tempList empty, and next code will be executed:
if (results.count == 0) {
notifyDataSetInvalidated();
}
Ok, after a lot of attempts, I've found the solution.
There was, obviously, a logic error: in the "filter" I was updating the wrong ArrayList of movies. The one that the adapter uses for building up the GridView in my app is "tempMovies" ArrayList.
In the "filter" I was using "tempList" and then updating "filterResults", but never updating "tempMovies". Even in the "getFilter" method.
Furthermore, I've found an easier to understand and to apply "filter" method. I'm using it and it works perfectly.
Here you are the code:
public void filter(CharSequence text){
String query = text.toString().toLowerCase();
tempMovies.clear();
if(text.length() == 0){
tempMovies.addAll(originalMoviesList);
} else{
for(Movies m : originalMoviesList){
if(m.toString().toLowerCase().contains(query)){
tempMovies.add(m);
}
}
}
notifyDataSetChanged();
}
I found it at this site:
http://www.androidbegin.com/tutorial/android-search-listview-using-filter/
In the end, thank you again to all of you who tried to help. I hope my experience will be usefull to others.
I trying to add admob native ads in recyclerview that uses resourcecursoradapter adapter .. the issues is
1 - it makes app crash
2 - it replaces recyclerview data item with admob ads
that is my code
public class EntriesCursorAdapter extends ResourceCursorAdapter {
private final Uri mUri;
private final boolean mShowFeedInfo;
private int mIdPos, mTitlePos, mMainImgPos, mDatePos, mIsReadPos, mFavoritePos, mFeedIdPos, mFeedNamePos;
public static final int Ads_view_type = 11;
public EntriesCursorAdapter(Context context, Uri uri, Cursor cursor, boolean showFeedInfo) {
super(context, PrefUtils.getInt(PrefUtils.NEWS_FORMAT_int,R.layout.item_entry_list2), cursor, 0);
mUri = uri;
mShowFeedInfo = showFeedInfo;
reinit(cursor);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final int position = cursor.getPosition();
final int viewtype = getItemViewType(position);
View itemView ;
if(viewtype == Ads_view_type) {
final LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(R.layout.native_ads, parent, false);
if (itemView.getTag(R.id.holder) == null) {
AdsHolder ads_holder = new AdsHolder();
ads_holder.adView = (NativeExpressAdView) itemView.findViewById(R.id.adView2);
itemView.setTag(R.id.holder, ads_holder);
} return itemView;
}
else {
final LayoutInflater inflater = LayoutInflater.from(context);
itemView = inflater.inflate(PrefUtils.getInt(PrefUtils.NEWS_FORMAT_int, R.layout.item_entry_list2), parent, false);
if (itemView.getTag(R.id.holder) == null) {
ViewHolder holder = new ViewHolder();
holder.titleTextView = (TextView) itemView.findViewById(android.R.id.text1);
holder.dateTextView = (TextView) itemView.findViewById(android.R.id.text2);
holder.mainImgView = (ImageView) itemView.findViewById(R.id.main_icon);
holder.starImgView = (ImageView) itemView.findViewById(R.id.favorite_icon);
itemView.setTag(R.id.holder, holder);
}
return itemView;
}
}
#Override
public int getItemViewType(int position) {
if(position % 6 ==0)
{return Ads_view_type;}
else {
return super.getItemViewType(position);
}
}
#Override
public void bindView(View view, final Context context, Cursor cursor) {
final int position = cursor.getPosition();
final int viewtype = getItemViewType(position);
if (viewtype == Ads_view_type) {
try {
AdsHolder adsHolder = (AdsHolder) view.getTag(R.id.holder);
AdRequest request = new AdRequest.Builder()
.addTestDevice("ca-app-pub-5647351014779121/8591922893")
.build();
adsHolder.adView.loadAd(request);
} catch (Exception e) {
}
} else {
try {
ViewHolder holder = (ViewHolder) view.getTag(R.id.holder);
String titleText = cursor.getString(mTitlePos);
holder.titleTextView.setText(titleText);
final long feedId = cursor.getLong(mFeedIdPos);
String feedName = cursor.getString(mFeedNamePos);
String mainImgUrl = cursor.getString(mMainImgPos);
mainImgUrl = TextUtils.isEmpty(mainImgUrl) ? null : NetworkUtils.getDownloadedOrDistantImageUrl(cursor.getLong(mIdPos), mainImgUrl);
ColorGenerator generator = ColorGenerator.DEFAULT;
int color = generator.getColor(feedId); // The color is specific to the feedId (which shouldn't change)
String lettersForName = feedName != null ? (feedName.length() < 2 ? feedName.toUpperCase() : feedName.substring(0, 2).toUpperCase()) : "";
TextDrawable letterDrawable = TextDrawable.builder().buildRect(lettersForName, color);
if (mainImgUrl != null) {
Glide.with(context).load(mainImgUrl).centerCrop().placeholder(letterDrawable).error(letterDrawable).into(holder.mainImgView);
} else {
Glide.clear(holder.mainImgView);
holder.mainImgView.setImageDrawable(letterDrawable);
}
holder.isFavorite = cursor.getInt(mFavoritePos) == 1;
holder.starImgView.setVisibility(holder.isFavorite ? View.VISIBLE : View.INVISIBLE);
if (mShowFeedInfo && mFeedNamePos > -1) {
if (feedName != null) {
holder.dateTextView.setText(Html.fromHtml("<font color='#247ab0'>" + feedName + "</font>" + Constants.COMMA_SPACE + StringUtils.getDateTimeString(cursor.getLong(mDatePos))));
} else {
holder.dateTextView.setText(StringUtils.getDateTimeString(cursor.getLong(mDatePos)));
}
} else {
holder.dateTextView.setText(StringUtils.getDateTimeString(cursor.getLong(mDatePos)));
}
if (cursor.isNull(mIsReadPos)) {
holder.titleTextView.setEnabled(true);
holder.dateTextView.setEnabled(true);
holder.isRead = false;
} else {
holder.titleTextView.setEnabled(false);
holder.dateTextView.setEnabled(false);
holder.isRead = true;
}
} catch (Exception e) {}
}
}
public void toggleReadState(final long id, View view) {
final ViewHolder holder = (ViewHolder) view.getTag(R.id.holder);
if (holder != null) { // should not happen, but I had a crash with this on PlayStore...
holder.isRead = !holder.isRead;
if (holder.isRead) {
holder.titleTextView.setEnabled(false);
holder.dateTextView.setEnabled(false);
} else {
holder.titleTextView.setEnabled(true);
holder.dateTextView.setEnabled(true);
}
new Thread() {
#Override
public void run() {
ContentResolver cr = MainApplication.getContext().getContentResolver();
Uri entryUri = ContentUris.withAppendedId(mUri, id);
cr.update(entryUri, holder.isRead ? FeedData.getReadContentValues() : FeedData.getUnreadContentValues(), null, null);
}
}.start();
}
}
public void toggleFavoriteState(final long id, View view) {
final ViewHolder holder = (ViewHolder) view.getTag(R.id.holder);
if (holder != null) { // should not happen, but I had a crash with this on PlayStore...
holder.isFavorite = !holder.isFavorite;
if (holder.isFavorite) {
holder.starImgView.setVisibility(View.VISIBLE);
} else {
holder.starImgView.setVisibility(View.INVISIBLE);
}
new Thread() {
#Override
public void run() {
ContentValues values = new ContentValues();
values.put(EntryColumns.IS_FAVORITE, holder.isFavorite ? 1 : 0);
ContentResolver cr = MainApplication.getContext().getContentResolver();
Uri entryUri = ContentUris.withAppendedId(mUri, id);
cr.update(entryUri, values, null, null);
}
}.start();
}
}
#Override
public void changeCursor(Cursor cursor) {
reinit(cursor);
super.changeCursor(cursor);
}
#Override
public Cursor swapCursor(Cursor newCursor) {
reinit(newCursor);
return super.swapCursor(newCursor);
}
#Override
public void notifyDataSetChanged() {
reinit(null);
super.notifyDataSetChanged();
}
#Override
public void notifyDataSetInvalidated() {
reinit(null);
super.notifyDataSetInvalidated();
}
private void reinit(Cursor cursor) {
if (cursor != null && cursor.getCount() > 0) {
mIdPos = cursor.getColumnIndex(EntryColumns._ID);
mTitlePos = cursor.getColumnIndex(EntryColumns.TITLE);
mMainImgPos = cursor.getColumnIndex(EntryColumns.IMAGE_URL);
mDatePos = cursor.getColumnIndex(EntryColumns.DATE);
mIsReadPos = cursor.getColumnIndex(EntryColumns.IS_READ);
mFavoritePos = cursor.getColumnIndex(EntryColumns.IS_FAVORITE);
mFeedNamePos = cursor.getColumnIndex(FeedColumns.NAME);
mFeedIdPos = cursor.getColumnIndex(EntryColumns.FEED_ID);
}
}
private static class ViewHolder {
public TextView titleTextView;
public TextView dateTextView;
public ImageView mainImgView;
public ImageView starImgView;
public boolean isRead, isFavorite;
}
private static class AdsHolder {
NativeExpressAdView adView;
}
}
I have FirstscreenActivity, in which I use RecyclerView, (in this RecyclerView displays pictures of the projects which were created by a user), then user goes to the next Activity, where he creates new project and adds pictures there. When user comes back to the FirstScreenActivity, old project downloads one more time, and after that download new project.
How to make that old projects wouldn't download one more time after the changing the Activities (so there wouldn't be duplicates)?
public class FirstscreenActivity extends AppCompatActivity implements RecyclerItemClickListener.OnItemClickListener {
private MyAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
public static String mCurrentProject = null;
RecyclerView list;
static File[] listFile;
static File[] listFolders;
static int newpressed = 0;
public static ArrayList<Folder> FOLDERS = new ArrayList<>();
public static LruCache<String, Bitmap> mMemoryCache;
public static File[] listFile2;
public void getFromSdcardFolders() {
File file = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture", "Previews");
if (file.isDirectory()) {
listFolders = file.listFiles();
for (int i = 0; i < listFolders.length; i++) {
Folder folderobject = new Folder();
folderobject.setName(listFolders[i].getName());
Log.i("List of FOLDERS: ", String.valueOf(listFolders[i].getName()));
File picturelist = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Previews", listFolders[i].getName());
if (picturelist.isDirectory()) {
listFile = picturelist.listFiles();
for (int j = 0; j < listFile.length; j++) {
folderobject.addFile(listFile[j].getAbsolutePath());
}
}
FOLDERS.add(folderobject);
Log.wtf("TAG", "Folders size inside the getFRom:" + FOLDERS.size());
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.front);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
getSupportActionBar().setTitle("");
list = (RecyclerView) findViewById(R.id.list);
list.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getApplicationContext());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
list.addOnItemTouchListener(new RecyclerItemClickListener(this, this));
getFromSdcardFolders();
list.setLayoutManager(mLayoutManager);
mAdapter = new MyAdapter(this, FOLDERS);
list.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 4;
mMemoryCache
= new LruCache<String, Bitmap>(cacheSize) {
#Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addItem:
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");
Date now = new Date();
mCurrentProject = String.valueOf(formatter.format(now));
Log.d("newpressed: ", String.valueOf(newpressed));
Intent nextScreen = new Intent(getApplicationContext(), AudioRecord.class);
startActivity(nextScreen);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onItemClick(View childView, int position) {
File picturelist2 = new File(Environment.getExternalStorageDirectory() +
"/Audio_Recorder_Picture/Pictures", listFolders[position].getName());
if (picturelist2.isDirectory()) {
listFile2 = picturelist2.listFiles();
for (int i = 0; i < listFile2.length; i++) {
Log.i("LIST OF PICTURES: ", String.valueOf(listFile2[i]));
}
}
Intent viewScreen = new Intent(getApplicationContext(), ViewActivity.class);
viewScreen.putExtra("FILE_TAG", listFile2);
startActivity(viewScreen);
}
#Override
public void onItemLongPress(View childView, int position) {
}
}
Code of the adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>` {
public final Activity context;
public final ArrayList<Folder> FOLDERS;
View view;
public long getItemId(int position) {
return position;
}
#Override
public int getItemCount() {
Log.wtf("TAG", "Folders size: " + FOLDERS.size());
return FOLDERS.size();
}
// optimisation of bitmap
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String path,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public void loadBitmap(String path, ImageView imageView, int position) {
final String imageKey = String.valueOf(path);
Bitmap bitmap = getBitmapFromMemCache(imageKey);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
bitmap = decodeSampledBitmapFromResource(path, 100, 100);
imageView.setImageBitmap(bitmap);
// BitmapWorkerTask task = new BitmapWorkerTask(imageView, position);
// task.execute(path);
}
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public TextView title;
public ImageView image1;
ImageView image2;
ImageView image3;
ImageView image4;
ImageView image5;
TextView slides;
public ViewHolder(View v) {
super(v);
title = (TextView) v.findViewById(R.id.item);
image1 = (ImageView) v.findViewById(R.id.icon1);
image2 = (ImageView) v.findViewById(R.id.icon2);
image3 = (ImageView) v.findViewById(R.id.icon3);
image4 = (ImageView) v.findViewById(R.id.icon4);
image5 = (ImageView) v.findViewById(R.id.icon5);
slides = (TextView) v.findViewById(R.id.textView1);
}
}
public MyAdapter(Activity context, ArrayList<Folder> FOLDERS) {
this.context = context;
this.FOLDERS = FOLDERS;
getItemCount();
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.wtf("TAG", "OnCreateViewHolder works!!!");
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.mylist, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Folder folder = FOLDERS.get(position);
holder.image1.setImageResource(R.drawable.placeholder);
holder.image2.setImageResource(R.drawable.placeholder);
holder.image3.setImageResource(R.drawable.placeholder);
holder.image4.setImageResource(R.drawable.placeholder);
holder.image5.setImageResource(R.drawable.placeholder);
ArrayList<String> imgs = folder.getPicturelist();
holder.title.setText(folder.getName());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 10;
for (int i = 0; i < 5; i++) {
switch (i) {
case 0:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image1, position);
} else {
holder.image1.setImageBitmap(null);
// holder.image1.setImageResource(R.drawable.placeholder);
}
break;
case 1:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image2, position);
} else {
holder.image2.setImageBitmap(null);
// holder.image2.setImageResource(R.drawable.placeholder);
}
break;
case 2:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image3, position);
} else {
holder.image3.setImageBitmap(null);
// holder.image3.setImageResource(R.drawable.placeholder);
}
break;
case 3:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image4, position);
} else {
holder.image4.setImageBitmap(null);
// holder.image4.setImageResource(R.drawable.placeholder);
}
break;
case 4:
if (imgs.size() > i && imgs.size() != 0) {
loadBitmap(imgs.get(i), holder.image5, position);
} else {
holder.image5.setImageBitmap(null);
// holder.image5.setImageResource(R.drawable.placeholder);
}
break;
}
}
holder.slides.setText("Количество слайдов: " + imgs.size());
view.setTag(holder);
}
public Bitmap getBitmapFromMemCache(String key) {
return com.example.attracti.audiorecorderpicture.FirstscreenActivity.mMemoryCache.get(key);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myproject">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"
android:name=".model.App"
>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<activity android:name=".activities.AudioRecord"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity android:name=".activities.FirstscreenActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.ViewActivity">
</activity>
</application>
</manifest>
Solution
If you are going back to first activity with intent, it will create the activity again, as expected. To prevent this, you can add this to manifest:
<activity android:name=".activities.FirstscreenActivity"
android:launchMode= "singleInstance"
...
singleInstance will create activity only once.
Solution
Use finish() when you want to go back.
I am using PagerSlidingTabStrip in an Android project.
When I swipe through the tabs, it is working correctly.
However, when I click on a tab, the tab does not change.
Here is the activity XML:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<au.edu.me.meandroidapplication.view.thirdparty.PagerSlidingTabStrip
android:id="#+id/progress_pager_tab_strip"
android:layout_width="match_parent"
android:layout_height="48dip"
app:pstsShouldExpand="true"
app:pstsIndicatorColor="#color/meTabIndicator"
app:pstsDividerColor="#color/meTabSeparator"
android:background="#color/meTabBackground" />
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/progressViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="au.edu.me.meandroidapplication.view.activity.MyProgressActivity" />
</RelativeLayout>
Here is my code in onCreate():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_progress);
this.viewPager = (ViewPager)this.findViewById(R.id.progressViewPager);
this.pagerAdapter = new MyProgressFragmentPagerAdapter(this.getSupportFragmentManager());
this.viewPager.setAdapter(this.pagerAdapter);
PagerSlidingTabStrip pagerTabStrip = (PagerSlidingTabStrip)this.findViewById(R.id.progress_pager_tab_strip);
pagerTabStrip.setViewPager(this.viewPager);
pagerTabStrip.setTextColorResource(R.color.meTabText);
}
Any advice on how to click the buttons to also change the tabs would be greatly appreciated!
Edit: yes the importing is from this project and not any other one. here is the code for PagerSlidingTabStrip
package au.edu.me.meandroidapplication.view.thirdparty;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.Locale;
import au.edu.me.meandroidapplication.R;
public class PagerSlidingTabStrip extends HorizontalScrollView {
public interface IconTabProvider {
public int getPageIconResId(int position);
}
// #formatter:off
private static final int[] ATTRS = new int[] {
android.R.attr.textSize,
android.R.attr.textColor
};
// #formatter:on
private LinearLayout.LayoutParams defaultTabLayoutParams;
private LinearLayout.LayoutParams expandedTabLayoutParams;
private final PageListener pageListener = new PageListener();
public OnPageChangeListener delegatePageListener;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF666666;
private int underlineColor = 0x1A000000;
private int dividerColor = 0x1A000000;
private boolean shouldExpand = false;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 8;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 24;
private int dividerWidth = 1;
private int tabTextSize = 12;
private int tabTextColor = 0xFF666666;
private Typeface tabTypeface = null;
private int tabTypefaceStyle = Typeface.BOLD;
private int lastScrollX = 0;
private int tabBackgroundResId = -1; // ### REMOVED
private Locale locale;
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
tabTextColor = a.getColor(1, tabTextColor);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
pager.setOnPageChangeListener(pageListener);
notifyDataSetChanged();
}
public void setOnPageChangeListener(OnPageChangeListener listener) {
this.delegatePageListener = listener;
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
if (pager.getAdapter() instanceof IconTabProvider) {
addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
} else {
addTextTab(i, pager.getAdapter().getPageTitle(i).toString());
}
}
updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
scrollToChild(currentPosition, 0);
}
});
}
private void addTextTab(final int position, String title) {
TextView tab = new TextView(getContext());
tab.setText(title);
tab.setGravity(Gravity.CENTER);
tab.setSingleLine();
addTab(position, tab);
}
private void addIconTab(final int position, int resId) {
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
addTab(position, tab);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
pager.setCurrentItem(position);
}
});
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
}
private void updateTabStyles() {
for (int i = 0; i < tabCount; i++) {
View v = tabsContainer.getChildAt(i);
// v.setBackgroundResource(tabBackgroundResId); // ### removed
if (v instanceof TextView) {
TextView tab = (TextView) v;
tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
tab.setTypeface(tabTypeface, tabTypefaceStyle);
tab.setTextColor(tabTextColor);
// setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
// pre-ICS-build
if (textAllCaps) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
tab.setAllCaps(true);
} else {
tab.setText(tab.getText().toString().toUpperCase(locale));
}
}
}
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw divider
dividerPaint.setColor(dividerColor);
for (int i = 0; i < tabCount - 1; i++) {
View tab = tabsContainer.getChildAt(i);
canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
}
}
private class PageListener implements OnPageChangeListener {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
if (delegatePageListener != null) {
delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
if (delegatePageListener != null) {
delegatePageListener.onPageScrollStateChanged(state);
}
}
#Override
public void onPageSelected(int position) {
if (delegatePageListener != null) {
delegatePageListener.onPageSelected(position);
}
}
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public void setShouldExpand(boolean shouldExpand) {
this.shouldExpand = shouldExpand;
requestLayout();
}
public boolean getShouldExpand() {
return shouldExpand;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public void setTextSize(int textSizePx) {
this.tabTextSize = textSizePx;
updateTabStyles();
}
public int getTextSize() {
return tabTextSize;
}
public void setTextColor(int textColor) {
this.tabTextColor = textColor;
updateTabStyles();
}
public void setTextColorResource(int resId) {
this.tabTextColor = getResources().getColor(resId);
updateTabStyles();
}
public int getTextColor() {
return tabTextColor;
}
public void setTypeface(Typeface typeface, int style) {
this.tabTypeface = typeface;
this.tabTypefaceStyle = style;
updateTabStyles();
}
public void setTabBackground(int resId) {
this.tabBackgroundResId = resId;
}
public int getTabBackground() {
return tabBackgroundResId;
}
public void setTabPaddingLeftRight(int paddingPx) {
this.tabPadding = paddingPx;
updateTabStyles();
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
currentPosition = savedState.currentPosition;
requestLayout();
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
#Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
#Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}