Bug in app while rotating Android phone - android

hello guys i started to learn to build android applications via udacy. After a long troubleshooting i didnt find something that can cause the bug that i have. the bug is that when i rotate the phone the view seems to clone it self and not deleting the previous one if someone can help me ill be very happy.
1) normal state of app:
2) after rotation:
3) and after another rotation the application crashing
it never happend until i added the code in the xml file of the view:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for weather forecast list item for future day (not today) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:id="#+id/list_item_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:paddingLeft="16dp">
<TextView
android:id="#+id/list_item_date_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tomorrow"/>
<TextView
android:id="#+id/list_item_forecast_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="right">
<TextView
android:id="#+id/list_item_high_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="81"
android:paddingLeft="10dp"/>
<TextView
android:id="#+id/list_item_low_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="68"
android:paddingLeft="10dp"/>
</LinearLayout>
</LinearLayout>
Activity Code:
package com.example.andy.sunshine.app;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
private String FORECASTFRAGMENT_TAG = "FFTAG";
String mLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment, new MainActivityFragment(), FORECASTFRAGMENT_TAG)
.commit();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mLocation = Utility.getPreferredLocation(this);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
protected void onResume() {
super.onResume();
String location = Utility.getPreferredLocation(this);
if(location != null && location != mLocation){
MainActivityFragment ff = (MainActivityFragment)getSupportFragmentManager().findFragmentById(R.id.fragment);
if(ff != null){
ff.onLocationChanged();
}
mLocation = location;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if(id == R.id.action_settings){
Intent settings = new Intent(this,SettingsActivity.class);
startActivity(settings);
}
if(R.id.action_map == id){
openPreferedLocationMap();
}
return super.onOptionsItemSelected(item);
}
private void openPreferedLocationMap(){
String location = Utility.getPreferredLocation(this);
Uri geoLocation = Uri.parse("geo:0,0?").buildUpon().appendQueryParameter("q",location).build();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(geoLocation);
if(intent.resolveActivity(getPackageManager()) != null){
startActivity(intent);
}
else{
Log.d("SHOWING MAP PROBLEMM","could't call"+ location+ "intent");
}
}
}
Fragment Code:
package com.example.andy.sunshine.app;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.andy.sunshine.app.data.WeatherContract;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* A placeholder fragment containing a simple view.
*/
public class MainActivityFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int FORECAST_LOADER = 0;
// For the forecast view we're showing only a small subset of the stored data.
// Specify the columns we need.
private static final String[] FORECAST_COLUMNS = {
// In this case the id needs to be fully qualified with a table name, since
// the content provider joins the location & weather tables in the background
// (both have an _id column)
// On the one hand, that's annoying. On the other, you can search the weather table
// using the location set by the user, which is only in the Location table.
// So the convenience is worth it.
WeatherContract.WeatherEntry.TABLE_NAME + "." + WeatherContract.WeatherEntry._ID,
WeatherContract.WeatherEntry.COLUMN_DATE,
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC,
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP,
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP,
WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING,
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID,
WeatherContract.LocationEntry.COLUMN_COORD_LAT,
WeatherContract.LocationEntry.COLUMN_COORD_LONG
};
// These indices are tied to FORECAST_COLUMNS. If FORECAST_COLUMNS changes, these
// must change.
static final int COL_WEATHER_ID = 0;
static final int COL_WEATHER_DATE = 1;
static final int COL_WEATHER_DESC = 2;
static final int COL_WEATHER_MAX_TEMP = 3;
static final int COL_WEATHER_MIN_TEMP = 4;
static final int COL_LOCATION_SETTING = 5;
static final int COL_WEATHER_CONDITION_ID = 6;
static final int COL_COORD_LAT = 7;
static final int COL_COORD_LONG = 8;
private ForecastAdapter mForecastAdapter;
public MainActivityFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.forecastfragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateWeather();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// The CursorAdapter will take data from our cursor and populate the ListView.
mForecastAdapter = new ForecastAdapter(getActivity(), null, 0);
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Get a reference to the ListView, and attach this adapter to it.
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(mForecastAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView adapterView, View view, int position, long l) {
// CursorAdapter returns a cursor at the correct position for getItem(), or null
// if it cannot seek to that position.
Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
if (cursor != null) {
String locationSetting = Utility.getPreferredLocation(getActivity());
Intent intent = new Intent(getActivity(), DetailActivity.class)
.setData(WeatherContract.WeatherEntry.buildWeatherLocationWithDate(
locationSetting, cursor.getLong(COL_WEATHER_DATE)
));
startActivity(intent);
}
}
});
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(FORECAST_LOADER, null, this);
super.onActivityCreated(savedInstanceState);
}
private void updateWeather() {
FetchWeatherTask weatherTask = new FetchWeatherTask(getActivity());
String location = Utility.getPreferredLocation(getActivity());
weatherTask.execute(location);
}
public void onLocationChanged(){
updateWeather();
getLoaderManager().restartLoader(FORECAST_LOADER,null,this);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String locationSetting = Utility.getPreferredLocation(getActivity());
// Sort order: Ascending, by date.
String sortOrder = WeatherContract.WeatherEntry.COLUMN_DATE + " ASC";
Uri weatherForLocationUri = WeatherContract.WeatherEntry.buildWeatherLocationWithStartDate(
locationSetting, System.currentTimeMillis());
return new CursorLoader(getActivity(),
weatherForLocationUri,
FORECAST_COLUMNS,
null,
null,
sortOrder);
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
mForecastAdapter.swapCursor(cursor);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
mForecastAdapter.swapCursor(null);
}
}
And Class That Extends CursorAdapter "ForecastAdapter":
package com.example.andy.sunshine.app;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.andy.sunshine.app.data.WeatherContract;
/**
* {#link ForecastAdapter} exposes a list of weather forecasts
* from a {#link android.database.Cursor} to a {#link android.widget.ListView}.
*/
public class ForecastAdapter extends CursorAdapter {
private final int VIEW_TYPE_TODAY = 0;
private final int VIEW_TYPE_FUTURE_DAY = 1;
public ForecastAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
}
#Override
public int getItemViewType(int position) {
return (position == 0)? VIEW_TYPE_TODAY:VIEW_TYPE_FUTURE_DAY;
}
#Override
public int getViewTypeCount() {
return 2;
}
/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(Context context,double high, double low) {
boolean isMetric = Utility.isMetric(mContext);
String highLowStr = Utility.formatTemperature(context,high, isMetric) + "/" + Utility.formatTemperature(context,low, isMetric);
return highLowStr;
}
/*
This is ported from FetchWeatherTask --- but now we go straight from the cursor to the
string.
*/
private String convertCursorRowToUXFormat(Context context,Cursor cursor) {
// get row indices for our cursor
String highAndLow = formatHighLows(context,
cursor.getDouble(MainActivityFragment.COL_WEATHER_MAX_TEMP),
cursor.getDouble(MainActivityFragment.COL_WEATHER_MAX_TEMP));
return Utility.formatDate(cursor.getLong(MainActivityFragment.COL_WEATHER_DATE)) +
" - " + cursor.getString(MainActivityFragment.COL_WEATHER_DESC) +
" - " + highAndLow;
}
/*
Remember that these views are reused as needed.
*/
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
int VIEW_TYPE = getItemViewType(cursor.getPosition());
int layoutId = -1;
if(VIEW_TYPE == VIEW_TYPE_TODAY){
layoutId = R.layout.list_item_forecast_today;
}else if(VIEW_TYPE == VIEW_TYPE_FUTURE_DAY){
layoutId = R.layout.list_item_forecast;
}
View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
MyViewHolder viewHolder = new MyViewHolder(view);
view.setTag(viewHolder);
return view;
}
/*
This is where we fill-in the views with the contents of the cursor.
*/
#Override
public void bindView(View view, Context context, Cursor cursor) {
// our view is pretty simple here --- just a text view
// we'll keep the UI functional with a simple (and slow!) binding.
MyViewHolder viewHolder = (MyViewHolder)view.getTag();
viewHolder.iconView.setImageResource(R.mipmap.ic_launcher);
// TODO Read date from cursor
long dateInMillis = cursor.getLong(MainActivityFragment.COL_WEATHER_DATE);
viewHolder.dateView.setText(Utility.getFriendlyDayString(context, dateInMillis));
// TODO Read weather forecast from cursor
viewHolder.descriptionView.setText(cursor.getString(MainActivityFragment.COL_WEATHER_DESC));
// Read user preference for metric or imperial temperature units
boolean isMetric = Utility.isMetric(context);
// Read high temperature from cursor
double high = cursor.getDouble(MainActivityFragment.COL_WEATHER_MAX_TEMP);
viewHolder.highTempView.setText(Utility.formatTemperature(context,high, isMetric));
// TODO Read low temperature from cursor
double low = cursor.getDouble(MainActivityFragment.COL_WEATHER_MIN_TEMP);
viewHolder.lowTempView.setText(Utility.formatTemperature(context,low, isMetric));
}
public static class MyViewHolder {
public final ImageView iconView;
public final TextView dateView;
public final TextView descriptionView;
public final TextView highTempView;
public final TextView lowTempView;
public MyViewHolder(View view){
iconView = (ImageView) view.findViewById(R.id.list_item_icon);
dateView = (TextView)view.findViewById(R.id.list_item_date_textview);
descriptionView = (TextView)view.findViewById(R.id.list_item_forecast_textview);
highTempView = (TextView)view.findViewById(R.id.list_item_high_textview);
lowTempView = (TextView)view.findViewById(R.id.list_item_low_textview);
}
}
}
if you want to see the whole project and check maybe for errors that may cause that i posting here my github https://github.com/obruchkov/Sunshine with all the code that i did. please help me guys

Related

How to use a ViewModel outside of onCreate()?

I have an Activity with a RecyclerView which display Livedata from a room database.
My aim is to start a new Activity with more data from the room database when the user is clicking on the corresponding item in the RecyclerView.
For that I overwrote the onClick() method in the adapter of the RecylcerView. Each object of the RecyclerView has a Id, I need that Id to get the corresponding data from the database. So I passed the Id from the Adapter to the Activity.
To search an element by Id in the database that I need the ViewModel object in the MainAcitivty. It is initialized in the onCreate() of the Activity. The method I called in the Adapter is outside the onCreate() and I get a null object reference exception when I try to use it.
How can I use the ViewModel outside of the onCreate() method of the Activity? Or is there another way to search for the element in the database?
Thank you!
The Adapter class:
In the onClick() method is the relevant part.
package com.example.fillmyplate.activities;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class RecipeAdapter extends RecyclerView.Adapter<RecipeAdapter.RecipeViewHolder> {
private static final String TAG = "RecipeAdapter";
private List<Recipe> mRecipes = new ArrayList<>();
private LayoutInflater mInflater;
private Context mContext;
private MainActivity mainActivity = new MainActivity();
private static int backGroundIndex = 0;
class RecipeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView recipeTitleItemView;
ImageView imageView;
public RecipeViewHolder(View itemView) {
super(itemView);
recipeTitleItemView = itemView.findViewById(R.id.name);
imageView = itemView.findViewById(R.id.card_image_view);
Log.d(TAG, "RecipeViewHolder: index " + backGroundIndex);
if (backGroundIndex == 0) {
imageView.setImageResource(R.drawable.background_green);
backGroundIndex++;
} else if (backGroundIndex == 1 ) {
imageView.setImageResource(R.drawable.background_red);
backGroundIndex++;
} else if (backGroundIndex == 2 ) {
imageView.setImageResource(R.drawable.background_blue);
backGroundIndex = 0;
}
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
// This should be the mistake.
mainActivity.startKnownRecipeActivity(position);
}
}
public RecipeAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.mContext = context;
}
#NonNull
#Override
public RecipeAdapter.RecipeViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// Inflate an item view
View mRecipeTitleView = mInflater.inflate(
R.layout.recipe_list_row, parent, false);
return new RecipeViewHolder(mRecipeTitleView);
}
// Get data into the corrsponding views
#Override
public void onBindViewHolder(RecipeAdapter.RecipeViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: " + position);
Recipe currentRecipe = mRecipes.get(position);
Log.d(TAG, "onBindViewHolder: setText " + currentRecipe);
holder.recipeTitleItemView.setText(currentRecipe.getTitle());
}
#Override
public int getItemCount() {
return mRecipes.size();
}
public void setRecipes(List<Recipe> recipes) {
this.mRecipes = recipes;
Log.d(TAG, "setRecipes: notifydataChanged" );
notifyDataSetChanged();
}
}
MainActivity:
package com.example.fillmyplate.activities;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.os.Build;
import android.os.Bundle;
import com.example.fillmyplate.R;
import com.example.fillmyplate.entitys.Recipe;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.cardview.widget.CardView;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainAcitivity";
private static final int NEW_RECIPE_ACTIVITY_REQUEST_CODE = 1;
private RecyclerView mRecyclerView;
private RecipeViewModel mRecipeViewmodel;
private RecyclerView.LayoutManager layoutManager;
//private final List<String> mTitleList = new LinkedList<>();
//NEU for adapter
private List<String> recipeDataList = new ArrayList<>();
RecipeRoomDatabase db;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// RECYCLER VIEW STUFF
mRecyclerView = findViewById(R.id.recycler_view1);
mRecyclerView.setHasFixedSize(true);
// user linerar layout manager
layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
// specify an adapter
final RecipeAdapter recipeAdapter = new RecipeAdapter(this);
//mAdapter = new RecipeAdapter(this, mTitleList);
mRecyclerView.setAdapter(recipeAdapter);
mRecipeViewmodel = ViewModelProviders.of(this).get(RecipeViewModel.class);
mRecipeViewmodel.getAllRecipes().observe(this, new Observer<List<Recipe>>() {
#Override
public void onChanged(List<Recipe> recipes) {
Log.d(TAG, "onChanged: " + recipes.toString());
for (Recipe rec : recipes) {
Log.d(TAG, "onChanged: " + rec.getTitle());
Log.d(TAG, "onChanged: recipe id " + rec.getUid());
}
recipeAdapter.setRecipes(recipes);
}
});
// DB
db = Room.databaseBuilder(getApplicationContext(), RecipeRoomDatabase.class, "appdb").build();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddRecipeActivity.class);
startActivityForResult(intent, NEW_RECIPE_ACTIVITY_REQUEST_CODE);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: ");
if (requestCode == NEW_RECIPE_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Log.d(TAG, "onActivityResult: " + data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
// mTitleList.add(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
Recipe rec = new Recipe(data.getStringExtra(AddRecipeActivity.EXTRA_REPLY));
mRecipeViewmodel.insert(rec);
} else {
Toast.makeText(
getApplicationContext(),
"saved",
Toast.LENGTH_LONG).show();
}
}
public void startKnownRecipeActivity(int position) {
Log.d(TAG, "startKnownRecipeActivity: Position " + position);
LiveData<List<Recipe>> recipe = mRecipeViewmodel.findById(position);
if (recipe.getValue().size() > 1) {
Log.d(TAG, "startKnownRecipeActivity: Error database found more than one recipe.");
} else {
Log.d(TAG, "startKnownRecipeActivity: Start activity with recipe " + recipe.getValue().get(0).getTitle());
}
}
}
The thing you need to do is to use a call back to send position back to activity.
To make sure that view position is correct you need to override 3 functions in RecyclerView Adapter:
#Override
public int getItemCount() {
return filteredUsers.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
For the Callback just create an Interface:
public interface AdapterListener {
void onClick(int id);
void onClick(ViewModel object);
}
Make a method in your Recycler Adapter:
private AdapterListener adapterListener;
public void setAdapterListener(AdapterListener mCallback) {
this.adapterListener = mCallback;
}
Implement this Interface on your Activity then you will get both methods of the interface.
public class MainActivity extends AppCompatActivity implements AdapterListener{
Register the listener by calling the setAdapterListener method in your activity after the initialization of the RecyclerView
adapterObject.setAdapterListener(MainActivity.this);
Then the last thing you need to do is call interface method in your item onClickListener, where u can either pass the complete model or just the id of the model
adapterListener.onClick(modelObject.getId());
OR
adapterListener.onClick(modelObject);

How to add intent in viewpager

I want to add intent in sliding view pager. As I click different pages of the sliding view pager, a different activity must be called but I can't find the solution.
I have added image text and description in the view pager and a button is there in the layout
I think this would involve the use of page selected but earlier when I used onpageselected by using the position it opens up the page even if we are not clicking but I want to use intent here.
Adapterclass
package com.android.msahakyan.expandablenavigationdrawer.adapter;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.msahakyan.expandablenavigationdrawer.R;
import com.android.msahakyan.expandablenavigationdrawer.fragment.CardAdapter;
import com.android.msahakyan.expandablenavigationdrawer.fragment.CardItemString;
import java.util.ArrayList;
import java.util.List;
/**
* Created by tanis on 21-06-2018.
*/
public class CardPagerAdapterS extends PagerAdapter implements CardAdapter {
private List<CardView> mViews;
private List<CardItemString> mData;
private float mBaseElevation;
public CardPagerAdapterS() {
mData = new ArrayList<>();
mViews = new ArrayList<>();
}
public void addCardItemS(CardItemString item) {
mViews.add(null);
mData.add(item);
}
public float getBaseElevation() {
return mBaseElevation;
}
#Override
public CardView getCardViewAt(int position) {
return mViews.get(position);
}
#Override
public int getCount() {
return mData.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext())
.inflate(R.layout.adapter, container, false);
container.addView(view);
bind(mData.get(position), view);
CardView cardView = (CardView) view.findViewById(R.id.cardView);
if (mBaseElevation == 0) {
mBaseElevation = cardView.getCardElevation();
}
cardView.setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR);
mViews.set(position, cardView);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
mViews.set(position, null);
}
private void bind(CardItemString item, View view) {
TextView titleTextView = (TextView) view.findViewById(R.id.titleTextView);
TextView contentTextView = (TextView) view.findViewById( R.id.contentTextView);
ImageView imageView=(ImageView) view.findViewById( R.id.image12 ) ;
titleTextView.setText(item.getTitle());
contentTextView.setText(item.getText());
imageView.setImageResource( item.getImages() );
}
}
FragmentAction
package com.android.msahakyan.expandablenavigationdrawer.fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
//import android.support.v7.widget.LinearLayoutManager;
//import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.msahakyan.expandablenavigationdrawer.R;
import com.android.msahakyan.expandablenavigationdrawer.Registration;
import com.android.msahakyan.expandablenavigationdrawer.adapter.CardPagerAdapterS;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import in.goodiebag.carouselpicker.CarouselPicker;
import technolifestyle.com.imageslider.FlipperLayout;
import technolifestyle.com.imageslider.FlipperView;
/**
* A simple {#link Fragment} subclass.
* Use the {#link FragmentAction#newInstance} factory method to
* create an instance of this fragment.
*/
public class FragmentAction extends Fragment {
ViewPager mViewPager;
CardPagerAdapterS mCardAdapter;
ShadowTransformer mCardShadowTransformer;
private Context context;
ViewPager viewPager;
String titlesText [] = {" Website Design", " Digital Marketing", " Domain Registration", "Graphics Design", " Mobile Apps", " Server Hosting",
" Software Development", " Content Marketing", " Security (SSl)"};
String detailsArray [] = {
"Your website is your digital home. We create, design, redesign, develop, improvise, and implement. We make beautiful websites",
"We help your business reach potential customers on every possible digital device through all possible media channels ",
"To launch your website the first thing you need is the domain name. You can choose your domain name with us here ",
"We generate creative solutions and can create a wide range of graphic for your clients which match their business ",
"We are mobile. And we make you mobile. We make responsive websites and mobile apps which compliment your business ",
"When you are hosting your website in the India you will benefit from a higher ping rate and lowest latency ",
"Our team is competent at coding web apps with keen attention to detail & intuitive functionality that is high on design & creativity",
"Content is the heart of your digital presence. We create the right content with the right focus for your business",
"Secure your site with the world's leading provider of online security and get these exclusive features at no added cost",
};
int[] images = {R.drawable.website_design, R.drawable.digita,R.drawable.domain_registration,R.drawable.graphic,
R.drawable.mob,R.drawable.server,R.drawable.software_development,R.drawable.ontent,R.drawable.ssl};
private static final String KEY_MOVIE_TITLE = "key_title";
public FragmentAction() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment.
*
* #return A new instance of fragment FragmentAction.
*/
public static FragmentAction newInstance(String movieTitle) {
FragmentAction fragmentAction = new FragmentAction();
Bundle args = new Bundle();
args.putString(KEY_MOVIE_TITLE, movieTitle);
fragmentAction.setArguments(args);
return fragmentAction;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.fragment_action,container,false);
TextView txt = (TextView)v.findViewById( R.id.textView12 );
txt.setText("\u25BA Creative & Dedicated Team");
TextView txt1 = (TextView)v.findViewById( R.id.textView13 );
txt1.setText("\u25BA Affordable Cost");
TextView txt2 = (TextView)v.findViewById( R.id.textView14 );
txt2.setText("\u25BA Maintain Long Relationship");
TextView txt3 = (TextView)v.findViewById( R.id.textView15 );
txt3.setText("\u25BA Timely Deliverly ");
context = this.getContext();
mViewPager = (ViewPager)v.findViewById(R.id.viewpager1);
mCardAdapter = new CardPagerAdapterS();
for (int i=0; i<titlesText.length; i++){
mCardAdapter.addCardItemS(new CardItemString( titlesText[i], detailsArray[i],images[i]));
}
mCardShadowTransformer = new ShadowTransformer(mViewPager, mCardAdapter);
mViewPager.setAdapter(mCardAdapter);
mViewPager.setPageTransformer(false, mCardShadowTransformer);
mViewPager.setOffscreenPageLimit(3);
viewPager = (ViewPager)v.findViewById( R.id.viewpager );
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter( this.getContext() );
viewPager.setAdapter( viewPagerAdapter );
Timer timer = new Timer( );
timer.scheduleAtFixedRate( new Mytime(),2000,4000 );
FloatingActionButton floatingActionButton = (FloatingActionButton)v.findViewById( R.id.floatingActionButton );
floatingActionButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity( new Intent( getActivity(),Registration.class ) );
}
} );
return v;
}
public class Mytime extends TimerTask{
#Override
public void run() {
getActivity().runOnUiThread( new Runnable() {
#Override
public void run() {
if(viewPager.getCurrentItem() == 0) {
viewPager.setCurrentItem( 1 );
}
else if (viewPager.getCurrentItem()== 1){
viewPager.setCurrentItem( 2 );
}
else if (viewPager.getCurrentItem()== 2){
viewPager.setCurrentItem( 3 );
}
else if (viewPager.getCurrentItem()== 3){
viewPager.setCurrentItem( 4 );
}
else {
viewPager.setCurrentItem(0);
}
}
} );
}
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Drawable movieIcon = ResourcesCompat.getDrawable(getResources(), R.drawable.webdesign, getContext().getTheme());
String movieTitle = getArguments().getString(KEY_MOVIE_TITLE);
}
}
first of all onPageSelected listener is not really good idea in this case, because it is invoked every time when viewpager' current position changes (it's good for setting toolbar title, for example).
You can add another collection for Activities which can be invoked in CardPagerAdapterS, for example:
....
private List<CardItemString> mData;
private List<Class<? extends Activity> mActivities;
and use them to create click listener in order to open activities:
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext())
.inflate(R.layout.adapter, container, false);
container.addView(view);
bind(mData.get(position), view);
CardView cardView = (CardView) view.findViewById(R.id.cardView);
if (mBaseElevation == 0) {
mBaseElevation = cardView.getCardElevation();
}
cardView.setMaxCardElevation(mBaseElevation * MAX_ELEVATION_FACTOR);
cardView.setOnCLickListener(v-> {
context.startActivity(new Intent(context, mActivities.get(position));
});
mViews.set(position, cardView);
return view;
}

.setOnItemClicklistener not works

I would like to send my data from one activity to other with help of intent and uri but the task doesnt get accomplished
my main activity code
package com.example.vidit.inventoryapp;
import android.app.LoaderManager;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ListView;
import static android.R.attr.id;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
/** Identifier for the pet data loader */
private static final int ITEM_LOADER = 0;
/** Adapter for the ListView */
ItemCursorAdapter mCursorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,editor.class);
startActivity(intent);
}
});
ListView ItemListView = (ListView) findViewById(R.id.list);
// Find and set empty view on the ListView, so that it only shows when the list has 0 items.
View emptyView = findViewById(R.id.empty_view);
ItemListView.setEmptyView(emptyView);
// Setup an Adapter to create a list item for each row of pet data in the Cursor.
// There is no pet data yet (until the loader finishes) so pass in null for the Cursor.
mCursorAdapter = new ItemCursorAdapter(this, null);
ItemListView.setAdapter(mCursorAdapter);
// Setup the item click listener
ItemListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
// Create new intent to go to {#link EditorActivity}
Intent intent = new Intent(MainActivity.this,editor.class);
Uri itemUri = ContentUris.withAppendedId(ItemContract.ItemEntry.CONTENT_URI, id);
intent.setData(itemUri);
startActivity(intent);
}
});
// Kick off the loader
getLoaderManager().initLoader(ITEM_LOADER, null, this);
}
private void insertPet() {
// Create a ContentValues object where column names are the keys,
// and Toto's pet attributes are the values.
ContentValues values = new ContentValues();
values.put(ItemContract.ItemEntry.NAME, "Football");
values.put(ItemContract.ItemEntry.PRICE, 200);
values.put(ItemContract.ItemEntry.STATUS, ItemContract.ItemEntry.ACCEPTED);
values.put(ItemContract.ItemEntry.QUANTITY, 7);
// Insert a new row for Toto into the provider using the ContentResolver.
// Use the {#link PetEntry#CONTENT_URI} to indicate that we want to insert
// into the pets database table.
// Receive the new content URI that will allow us to access Toto's data in the future.
Uri newUri = getContentResolver().insert(ItemContract.ItemEntry.CONTENT_URI, values);
}
/**
* Helper method to delete all pets in the database.
*/
private void deleteAllPets() {
int rowsDeleted = getContentResolver().delete(ItemContract.ItemEntry.CONTENT_URI, null, null);
Log.v("CatalogActivity", rowsDeleted + " rows deleted from pet database");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection = {
ItemContract.ItemEntry._ID,
ItemContract.ItemEntry.NAME,
ItemContract.ItemEntry.PRICE,
ItemContract.ItemEntry.QUANTITY,
};
// This loader will execute the ContentProvider's query method on a background thread
return new CursorLoader(this, // Parent activity context
ItemContract.ItemEntry.CONTENT_URI, // Provider content URI to query
projection, // Columns to include in the resulting Cursor
null, // No selection clause
null, // No selection arguments
null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mCursorAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mCursorAdapter.swapCursor(null);
}
}
My adapter class:
package com.example.vidit.inventoryapp;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.TextView;
import static android.R.attr.id;
import static android.R.attr.order;
import static android.R.attr.value;
import static android.os.Build.VERSION_CODES.M;
public class ItemCursorAdapter extends CursorAdapter {
public ItemCursorAdapter(Context context, Cursor c) {
super(context, c, 0 /* flags */);
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Inflate a list item view using the layout specified in list_item.xml
return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
}
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
// Find individual views that we want to modify in the list item layout
TextView nameTextView = (TextView) view.findViewById(R.id.name);
TextView priceTextView = (TextView) view.findViewById(R.id.price);
final TextView quantityTextView = (TextView) view.findViewById(R.id.quantity);
Button sell=(Button) view.findViewById(R.id.sell);
Button order=(Button) view.findViewById(R.id.order);
Button detail =(Button) view.findViewById(R.id.detail);
// Find the columns of pet attributes that we're interested in
int nameColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.NAME);
int priceColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.PRICE);
int quantityColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry.QUANTITY);
// Read the attributes from the Cursor for the current pet
String itemName = cursor.getString(nameColumnIndex);
String itemPrice = cursor.getString(priceColumnIndex);
final String itemQuantity=cursor.getString(quantityColumnIndex);
if (TextUtils.isEmpty(itemPrice)) {
itemPrice = "Not known yet";
}
if (TextUtils.isEmpty(itemQuantity)) {
itemPrice = "Not known yet";
}
final int qua=Integer.parseInt(itemQuantity);
nameTextView.setText(itemName);
priceTextView.setText(itemPrice);
quantityTextView.setText(itemQuantity);
sell.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(Integer.parseInt(itemQuantity)>0)
{
int x=Integer.parseInt(itemQuantity)-1;
quantityTextView.setText("" + x);
int idColumnIndex = cursor.getColumnIndex(ItemContract.ItemEntry._ID);
int id = cursor.getInt(idColumnIndex);
Uri itemUri = ContentUris.withAppendedId(ItemContract.ItemEntry.CONTENT_URI, id);
ContentValues values = new ContentValues();
values.put(ItemContract.ItemEntry.QUANTITY, x);
context.getContentResolver().update(itemUri, values, null, null);
}
}
});
order.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
"mailto","abc#gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Body");
context.startActivity(Intent.createChooser(emailIntent, "Send email..."));
}
});
/* view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context,editor.class);
Uri itemUri = ContentUris.withAppendedId(ItemContract.ItemEntry.CONTENT_URI, id);
intent.setData(itemUri);
context.startActivity(intent);
}
});*/
}
}
if I add intent code which i have commented in adapter class itnet happens succesfully but no data is passed from list view to the intent .
Thanks in advance.

How to update fragment/update fragment ui from activity?

Pageviewer.java code:
//hide status bar/action bar on single tap
package com.app.imageswiper;
import android.app.ActionBar;
import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.design.widget.TabLayout;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
public class Pageviwer extends AppCompatActivity {
private Integer[] mImageIds = {R.drawable.page001, R.drawable.page002,
R.drawable.page003};
private static final String DEBUG_TAG = "pageviwer ";
ImageView imageView;
float startXValue = 1;
public int num;
public int click;
protected static final String TAG = "Pageviwer";
private GestureDetector mGestureDetector;
public SharedPreferences prefs;
public static int Bookmark = 0;
public static int Pageno = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
int Bookmark1 = prefs.getInt("Bookmark", 0);
Bookmark = Bookmark1;
prefs = PreferenceManager.getDefaultSharedPreferences(this);
int Pageno1 = prefs.getInt("Pageno", 0);
Pageno = Pageno1;
setContentView(R.layout.pageviwer);
imageView = (ImageView) findViewById(R.id.image_place_holder);
imageView.setImageResource(mImageIds[0]);
TextView tv1 = (TextView) findViewById(R.id.pageno);
tv1.setText("" + (num + 1));
Toast.makeText(getApplicationContext(), "value is " + num, Toast.LENGTH_LONG).show();
setupGestureDetector();
hideActionBar(); // hide action bar after 1 second
}
private void setupGestureDetector() {
mGestureDetector = new GestureDetector(this,
new GestureDetector.SimpleOnGestureListener() {
//Detecting Swipe/Fling Direction
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
Log.i(TAG, "onFling");
if (e1.getX() < e2.getX()) {
Log.d(TAG, "Left to Right swipe performed");
if (num == 2) {
num = num;
} else {
imageView.setImageResource(mImageIds[num + 1]);
num = num + 1;
}
TextView tv1 = (TextView) findViewById(R.id.pageno);
tv1.setText("" + (num + 1));
Toast.makeText(getApplicationContext(), "value is " + num, Toast.LENGTH_LONG).show();
}
if (e1.getX() > e2.getX()) {
Log.d(TAG, "Right to Left swipe performed");
if (num == 0) {
num = num;
} else {
imageView.setImageResource(mImageIds[num - 1]);
num = num - 1;
}
TextView tv1 = (TextView) findViewById(R.id.pageno);
tv1.setText("" + (num + 1));
Toast.makeText(getApplicationContext(), "value is " + num, Toast.LENGTH_LONG).show();
}
return true;
}
//detecting single tap
#Override
public boolean onSingleTapUp(MotionEvent e) {
Log.i(TAG, "onSingleTapUp");
Toast.makeText(getApplicationContext(), "Single Tap ", Toast.LENGTH_LONG).show();
//Remove notification bar and action bar
if (click == 0) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
if (getSupportActionBar() != null) getSupportActionBar().hide();
click = 1;
}
//Return notification bar and action bar
else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
if (getSupportActionBar() != null) getSupportActionBar().show();
click = 0;
}
return true;
}
});
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector != null) {
return mGestureDetector.onTouchEvent(event);
} else {
return super.onTouchEvent(event);
}
}
public void hideActionBar() {
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
// DO DELAYED STUFF
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
if (getSupportActionBar() != null) getSupportActionBar().hide();
click = 1;
}
}, 1000); // 1000 milliseconds (1 second)
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == com.app.imageswiper.R.id.action_settings) {
Bookmark=1;
prefs.edit().putInt("Bookmark", Bookmark).commit();
prefs.edit().putInt("Pageno", num).commit();
Toast.makeText(getApplicationContext(), "Bookmark value is "+Bookmark, Toast.LENGTH_LONG).show();
}
return super.onOptionsItemSelected(item);
}
}
ViewPagerAdapter code:
package com.app.imageswiper;
/**
* Created by Jaffer on 14-Apr-16.
*/
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class Bookmarks extends Fragment {
public SharedPreferences prefs;
public static int Bookmark = 0;
public static int Pageno = 0;
Button sendButton = null;
View inflatedView = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
int Bookmark1 = prefs.getInt("Bookmark", 0);
Bookmark = Bookmark1;
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
int Pageno1 = prefs.getInt("Pageno", 0);
Pageno = Pageno1;
this.inflatedView = inflater.inflate(R.layout.bookmarks, container, false);
sendButton = (Button) inflatedView.findViewById(R.id.bookmark);
if(Bookmark==1){sendButton.setText("Page "+Pageno);}
else {sendButton.setText("No Bookmark ");}
if(sendButton == null)
{
Log.d("debugCheck", "HeadFrag: sendButton is null");
return inflatedView;
}
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), Pageviwer.class);
startActivity(intent);
}
});
return inflatedView;
}
}
bookmarks.xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/bookmarks">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
style="#style/Widget.AppCompat.Button.Borderless"
android:id="#+id/bookmark"
android:layout_alignParentBottom="true" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#android:color/darker_gray"/>
</LinearLayout>
I don't know how to update the button text from Pageviewer.java for the button with R.id.bookmark that shows up on the Bookmarks fragment on the click of menu item R.id.action_settings. I want to do this so that the button text corresponds to the page that is being bookmarked. I tried alot of things but to no avail. Can someone please help me with anything?
Thanks in advance
Create a method in your fragment to update the text of your button.
public void updateText(String newText){
//assuming button is globally declared in your fragment.
button.setText(newText);
}
Instead of Gesture Detector you could use a ViewPager which supports swiping to the left and right.You can find a sample implementation here.
Then in your Activty,implement PageChanegListener on ViewPager.
viewPager.addOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
// Check if this is the page you want.You have to implement viewpager's adapter with getItem(index) which returns a fragment at that index.
BookMarkFragment fragment (BookMarkFragment)mAdapter.getItem(position);
fragment.updateText(newText);
};
});
You should save the state of a button somewhere. Your field int Bookmark == 0, so expression sendButton.setText("Page "+Pageno); never execute. Save the state in SharedPreferences and get this state. Like this:
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
int isBookmark = prefs.getInt("Bookmark", 0);
int mPageno = prefs.getInt("Pageno", 0);
...
if(isBookmark == 1){
sendButton.setText("Page " + mPageno);
} else {
sendButton.setText("No Bookmark");
}

android check if item clicked

I just started with Android programming and here's the thing.
How can i check if the item in GridView was already clicked? Something like assigning a boolean 'clicked' for EACH item in Grid and changing it's value every time i click the item.
Currently i'm just using an array of bools so if i click item[x] it switches the bool[x] and then i do the check if it's true/false and modify the item accordingly, but there has to be a neater way of doing the same!
My code:
package com.example.mojrecnik;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
public class Glavna extends Activity implements AdapterView.OnItemClickListener {
private static final int LENGTH_SHORT = 0;
GridView grid;
TextView tekst;
String[] izfajla = new String[200];
String[] izfajla2 = new String[200];
boolean[] kliknutmrs = new boolean[200];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_glavna);
grid=(GridView)findViewById(R.id.grid);
grid.setAdapter(new MojAdapter());
grid.setOnItemClickListener(this);
//tekst=(TextView)findViewById(R.id.tekst);
citaFajl();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_glavna, menu);
return true;
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
TextView klik = (TextView)arg1.findViewById(R.id.gridtekst2);
if(kliknutmrs[arg2]) {
kliknutmrs[arg2]=!kliknutmrs[arg2];
klik.setText(izfajla[arg2]); }
else {
kliknutmrs[arg2]=!kliknutmrs[arg2];
klik.setText(izfajla2[arg2]); }
}
public void onNothingSelected(AdapterView<?> arg0) {
}
public void citaFajl() {
File kartica = Environment.getExternalStorageDirectory();
File fajl = new File(kartica, "reci.txt");
StringBuilder tekst = new StringBuilder();
int i=0;
try {
BufferedReader br = new BufferedReader(new FileReader(fajl));
String linija;
String[] prva;
while ((linija = br.readLine())!=null) {
prva = linija.split("-");
izfajla[i]=prva[0];
if(prva[1].length()>0)
izfajla2[i]=prva[1];
i++;
}
}
catch (IOException e) {
Toast greska = Toast.makeText(this, e.getMessage().toString(), LENGTH_SHORT);
greska.show();
}
}
private class MojAdapter extends ArrayAdapter {
public MojAdapter() {
super(Glavna.this, R.layout.gridvju, izfajla);
}
public View getView(int position, View convertView, ViewGroup parent) {
//vazno!! pravim vju od inflatera i vracam vju a ne convertvju!
View gridvju;
if(convertView==null) {
LayoutInflater inflater = getLayoutInflater();
gridvju = inflater.inflate(R.layout.gridvju, parent, false);
}
else
gridvju=convertView;
TextView tekst2 = (TextView)gridvju.findViewById(R.id.gridtekst2);
tekst2.setLines(2);
tekst2.setText(izfajla[position]);
return(gridvju);
}
}
}
And XML(main):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
<TextView
android:id="#+id/tekst"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:textSize="20dp"
android:layout_below="#id/tekst" >
</TextView> -->
<GridView
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:horizontalSpacing="#dimen/padding_medium"
android:numColumns="3"
android:stretchMode="columnWidth" >
</GridView>
</RelativeLayout>
And layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/gridtekst2" />
</LinearLayout>
Here is how i worked it in the end. I created a custom class to contain text which is displayed and also added a bool in there so now every element in my gridview has its own 'click-checker'.
note: this program simply alternates between 2 words onClick, if you wanna try it use text file with data formated 'word1 - word2'
Code:
package com.example.mojrecnik;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;
public class Glavna extends Activity implements AdapterView.OnItemClickListener {
private static final int LENGTH_LONG = 1;
GridView grid;
List<Rec> lReci = new ArrayList<Rec>(); //this is our list of data which contains text and bool check
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_glavna);
citaFajl();
grid=(GridView)findViewById(R.id.grid);
grid.setAdapter(new MojAdapter());
grid.setOnItemClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_glavna, menu);
return true;
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
VjuHolder holder=(VjuHolder)arg1.getTag();
if(!lReci.get(arg2).clicked)
holder.text.setText(lReci.get(arg2).rec2);
else
holder.text.setText(lReci.get(arg2).rec1);
lReci.get(arg2).clicked = !lReci.get(arg2).clicked;
}
public void onNothingSelected(AdapterView<?> arg0) {
//////////////////////////////////////////
}
public void citaFajl() {
try {
BufferedReader br = new BufferedReader(new FileReader(new File(Environment.getExternalStorageDirectory(), "reci.txt")));
String[] reci = new String[2];
String linija;
Rec rec;
while ((linija = br.readLine()) != null) {
reci = linija.split("-"); //because data in my file is formatted 'word1 - word2', we separate them now so we can alternate between them
reci[1]=reci[1].trim();
rec = new Rec(reci[0], reci[1], false);
lReci.add(rec);
}
}
catch (IOException e) {
Toast.makeText(this, e.getMessage().toString(), LENGTH_LONG).show();
}
}
private class MojAdapter extends ArrayAdapter<String> {
public MojAdapter() {
super(Glavna.this, R.layout.gridvju);
}
public int getCount() {
return lReci.size(); //here we explicitly set the total number of grid elements so it doesn't go out of index range
}
public View getView(int position, View convertView, ViewGroup parent) {
VjuHolder holder;
if(convertView==null) {
LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(R.layout.gridvju, parent, false);
holder = new VjuHolder();
holder.text = (TextView)convertView.findViewById(R.id.gridtekst2);
convertView.setTag(holder); }
else
holder=(VjuHolder)convertView.getTag();
if(lReci.get(position).clicked) //check to make grid update according to the clicked state of our elements [when scrolling]
holder.text.setText(lReci.get(position).rec2);
else
holder.text.setText(lReci.get(position).rec1);
holder.text.setLines(2);
return(convertView);
}
}
}
//holder class
class VjuHolder {
TextView text;
}
//here we put the text to be displayed along with bool to check in which state is the clicked element
class Rec {
String rec1, rec2;
boolean clicked;
Rec(String rec, String druga, boolean klik) {
rec1 = rec;
rec2 = druga;
clicked = klik;
}
}
There's no such thing like "click history" retained. If user taps anything then, if there's onClickListener assigned, you will get notified about that tap. But you cannot check that by querying UI objects. Boolean array is ok, but I'd use List or ArrayList instead and simply add id of tapped items in my onClickListener.
There is no way to find out whether button was clicked before or not. I think you've been looking for some sort of class property like
if(button.wasOnceClicked){ //THERE IS NO CODE LIKE THIS
}
Am I right? Well, Button class dont have this.
However u can create subclass of Button and add that property and also add some code which will handle that property.
First of all initialize your boolean array in onCreate as:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_grid);
grid=(GridView)findViewById(R.id.grid);
grid.setAdapter(new MojAdapter());
grid.setOnItemClickListener(this);
// HERE I have initialized with true valuse
for(int i=0; i<kliknutmrs.length; i++) {
kliknutmrs[i] = true;
}
//tekst=(TextView)findViewById(R.id.tekst);
citaFajl();
}
Then at onClick, just ckeck that the boolean array hav "true" value; so make that position value "false" and same time invert the text value with another String[] array.
At second time it will goto to else part:
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
TextView klik = (TextView)arg1.findViewById(R.id.gridtekst2);
if(kliknutmrs[arg2]) {
System.out.println(" ------------ 11111111111 -----------");
kliknutmrs[arg2]=!kliknutmrs[arg2];
klik.setText(izfajla2[arg2]); }
else {
System.out.println(" ------------- 222222222 -----------");
// NO NEED //kliknutmrs[arg2]=!kliknutmrs[arg2];
klik.setText(izfajla2[arg2]); }
}

Categories

Resources