I'm trying take screenshot of a cardview which is in a DialogFragment. When I take a screenshot via Code. Top rounded corners are not showing but the bottom rounded corners are showing correctly. I saw these issues mentioned in the below Questions...
Cardview loses its radius when taken a screenshot programmatically
Using PixelCopy to copy a scaled View within a DialogFragment
As per the above question, I tested the same layout & code in a Fragment class. Then the rounded corners are showing up correctly...
LAYOUT
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/mainlinear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_margin="18dp">
<androidx.cardview.widget.CardView
android:id="#+id/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="28dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorCand"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="320dp"
android:background="#color/colorWhite"
android:scaleType="centerCrop"
android:src="#drawable/turtle" />
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/image"
android:background="#color/colorAccent">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/type"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:src="#drawable/ic_idea" />
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:maxLines="1"
android:textAlignment="textEnd"
android:textAllCaps="true"
android:textColor="#color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
tools:ignore="RtlCompat"
tools:text="Sea Turtle Day" />
</LinearLayout>
<RelativeLayout
android:id="#+id/desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:background="#color/colorGray">
<TextView
android:id="#+id/tag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="12dp"
android:layout_marginEnd="8dp"
android:layout_toStartOf="#id/category_icon"
android:maxLines="2"
android:textColor="#color/colorAccent"
tools:text="#SeaTurtleDay#SeaTurtleDay" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/category_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:src="#drawable/animals" />
</RelativeLayout>
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/logo"
android:layout_width="96dp"
android:layout_height="96dp"
android:layout_below="#+id/desc"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_margin="8dp"
android:src="#drawable/wwf_logo" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
ShotDialog.java
public class ShotDialog extends DialogFragment {
StkyrDialogBinding mBind;
private static Context mCon;
private static Boolean viaEntity;
private String mLink;
public ShotDialog() {
}
public static ShotDialognewInstance(Context context, Stkyr mStk, Boolean entityOnclick) {
StkyrDialog frag = new StkyrDialog();
mCon = context;
viaEntity = entityOnclick;
Bundle args = new Bundle();
args.putSerializable("STK", mStk);
frag.setArguments(args);
return frag;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mBind = ShotDialogBinding.inflate(inflater);
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mBind.fwd.setOnClickListener(view -> {
FragmentManager fm = ((FragmentActivity) mCon).getSupportFragmentManager();
BottomDialogFragment mBot = BottomDialogFragment.newInstance(mCon, mBind.mainlinear);
mBot.show(fm, "ShareDialog");
});
}
return mBind.getRoot();
}
}
BottomDialogFragment.java (From this Bottomsheet the screenshot code is triggered for the above Dialog)
public class BottomDialogFragment extends BottomSheetDialogFragment {
public static Context mCon;
private static View stkView;
DialogShareBinding mBind;
private String sharePath = "no";
public static BottomDialogFragment newInstance(Context context, View view) {
mCon = context;
stkView = view;
return new BottomDialogFragment();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mBind = DialogShareBinding.inflate(inflater);
return mBind.getRoot();
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mBind.stkShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
mBind.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
Log.e("onClick: ", "SS TRIGGER");
takeStkShot();
}
});
}
public void takeStkShot() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ViewImage.Companion.getScreenShotFromView(stkView, getActivity(), (bm) -> {
Log.e("takeStkShot: ", "> > >");
storeImage(bm);
return null;
});
} else {
Bitmap bm = ViewImage.Companion.getScreenShot(stkView);
storeImage(bm);
Log.e("takeStkShot: ", "> > > ScreenShot");
}
}
private void storeImage(Bitmap bm) {
Log.e("takeScreenshot: ", "STORING");
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd hh:mm", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg";
try {
Log.d("ShareImageCreate", bm.toString());
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bm.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
//setting screenshot in imageview
String filePath = imageFile.getPath();
Log.e("takeScreenshot > > ", filePath);
Bitmap ssbitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
//iv.setImageBitmap(ssbitmap);
sharePath = filePath;
Log.d("ShareImageCreate", sharePath);
Toast.makeText(getActivity(),"SCREENSHOT STORED!",Toast.LENGTH_SHORT).show();
} catch (NullPointerException ex) {
ex.printStackTrace();
}
} catch (Throwable e) {
// Several error may come out with file handling or DOM
e.printStackTrace();
}
}
}
ShotFragment.java (This Gives expected result with rounded corners)
public class ShotFragment extends Fragment {
String mEntityType = Constants.CAUSE;
Bundle mBundle;
ExtendedFloatingActionButton nextFab;
AppCompatImageView img;
CardView mCard;
private String sharePath = "no";
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.dialog_test, container, false);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Create Screenshot");
mCard = root.findViewById(R.id.cardView);
mCard.setOnClickListener(view -> {
takeStkShot();
return root;
}
public void takeStkShot() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ViewImage.Companion.getScreenShotFromView(mCard, getActivity(), (bm) -> {
Log.e("takeStkShot: ", "> > >");
storeImage(bm);
return null;
});
} else {
Bitmap bm = ViewImage.Companion.getScreenShot(mCard);
storeImage(bm);
Log.e("takeStkShot: ", "> > > ScreenShot");
}
}
private void storeImage(Bitmap bm) {
Log.e("takeScreenshot: ", "STORING");
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd hh:mm", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg";
// create bitmap screen capture
//View v1 = lyTakeScreenShots.getRootView();
try {
Log.d("ShareImageCreate", bm.toString());
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bm.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
//setting screenshot in imageview
String filePath = imageFile.getPath();
Log.e("takeScreenshot > > ", filePath);
Bitmap ssbitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
//iv.setImageBitmap(ssbitmap);
sharePath = filePath;
Log.d("ShareImageCreate", sharePath);
Toast.makeText(getActivity(),"SCREENSHOT STORED!",Toast.LENGTH_SHORT).show();
} catch (NullPointerException ex) {
ex.printStackTrace();
}
} catch (Throwable e) {
// Several error may come out with file handling or DOM
e.printStackTrace();
}
}
Try the following as a replacement for ViewImage.kt in the referenced project. The main change is to pass in the view's window rather than an Activity. Dialogs have their own windows and don't share a window with activities.
ViewImage.kt
/**
* Bulk of code borrowed from "Taking Screenshot Programmatically Using PixelCopy Api"
* by Shivesh Karan Mehta
* https://medium.com/#shiveshmehta09/taking-screenshot-programmatically-using-pixelcopy-api-83c84643b02a
*/
class ViewImage {
companion object {
#JvmStatic
fun getScreenShotFromView(view: View, window: Window, callback: (Bitmap) -> Unit) {
val bitmap: Bitmap
// PixelCopy is available since API 24 but doesn't seem to work 100% until API 29.
// The build version statement can be adjusted according to how well PixelCopy
// works in your environment before "P".
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val locationOfView = IntArray(2)
view.getLocationInWindow(locationOfView)
val rect = Rect(locationOfView[0], locationOfView[1],
locationOfView[0] + view.width, locationOfView[1] + view.height)
bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
try {
PixelCopy.request(window, rect, bitmap,
{ copyResult: Int ->
if (copyResult == PixelCopy.SUCCESS) {
callback(bitmap)
}
// possible to handle other result codes ...
},
Handler()
)
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace()
}
} else {
bitmap = getScreenShot(view)
callback(bitmap)
}
}
// Method which will return Bitmap after taking screenshot. We have to pass the view which
// we want to take screenshot.
#Suppress("DEPRECATION")
#JvmStatic
fun getScreenShot(view: View): Bitmap {
view.isDrawingCacheEnabled = true
val bitmap = Bitmap.createBitmap(view.drawingCache)
view.isDrawingCacheEnabled = false
return bitmap
}
}
}
I Noticed that you are trying to take a screenshot from 'mainRelative' which does not exist in your xml, I think you should use the id of 'cardView' or 'mainlinear' based on your requirements.
The Answer given by #Cheticamp is right
Lets Convert it into java
public class ScreenshotTaker {
private static final String TAG = ScreenshotTaker.class.getSimpleName();
/**
* Takes screenshot of given view and saves it in external storage
* #param view outer most ViewGroup that you want a screenshot of
* #return File object of saved screenshot in storage
*/
public static File captureScreenshot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return saveBitmap(view.getContext(),bitmap);
}
public interface screenshotFile{
void onComplete(File file);
}
public static void getScreenShotFromView(View view, Window window, screenshotFile callback ) {
Bitmap bitmap;
// PixelCopy is available since API 24 but doesn't seem to work 100% until API 29.
// The build version statement can be adjusted according to how well PixelCopy
// works in your environment before "P".
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
int[] locationOfView = new int[2];
view.getLocationInWindow(locationOfView);
Rect rect = new Rect(locationOfView[0], locationOfView[1],
locationOfView[0] + view.getWidth(), locationOfView[1] + view.getHeight());
bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
try {
PixelCopy.request(window, rect, bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
#Override
public void onPixelCopyFinished(int copyResult) {
if (copyResult == PixelCopy.SUCCESS) {
callback.onComplete(saveBitmap(view.getContext(),bitmap));
}
}
}, new Handler()
);
}catch (Exception ignored){ }
}
}
}
Related
In my app, I have integrated Mapbox and It was working fine. But now It's not loading a map in NavigationView. It is working fine in master branch but not working on the BLE features branch even though I have not changed anything in that Activity. Please find below code here, I am launching this NavigationActivity from MainActivity where user select origin and destination locations.
NavigationActivity-Screen:
NavigationActivity.java:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.mapbox.api.directions.v5.models.BannerText;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.api.directions.v5.models.LegStep;
import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions;
import com.mapbox.services.android.navigation.ui.v5.OnNavigationReadyCallback;
import com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader;
import com.mapbox.services.android.navigation.v5.milestone.BannerInstructionMilestone;
import com.mapbox.services.android.navigation.v5.milestone.Milestone;
import com.mapbox.services.android.navigation.v5.milestone.MilestoneEventListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import java.math.BigDecimal;
import java.util.List;
public class NavigationActivity extends AppCompatActivity implements MilestoneEventListener, OnNavigationReadyCallback {
private TextView myBanner;
ImageView next, previous;
List<LegStep> steps;
TextView tv_step;
int currentStepIndex = 0;
DirectionsRoute currentRoute = null ;
com.mapbox.services.android.navigation.ui.v5.NavigationView navigationView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigations);
navigationView = findViewById(R.id.navigationView);
myBanner = findViewById(R.id.dummyBanner);
tv_step = findViewById(R.id.tv_step);
next = findViewById(R.id.iv_next);
previous = findViewById(R.id.iv_previous);
navigationView.onCreate(savedInstanceState);
navigationView.initialize(this);
try{
currentRoute = (DirectionsRoute) getIntent().getSerializableExtra("route");
if(currentRoute != null){
steps = currentRoute.legs().get(0).steps();
if(steps.size() > 0){
setup();
}
}
}catch (Exception e){}
}
private void setup(){
loadText( 0);
next.setOnClickListener((View v )-> {
if (currentStepIndex < steps.size() - 2)
loadText(++currentStepIndex);
});
previous.setOnClickListener((View v )-> {
if (currentStepIndex > 0)
loadText(--currentStepIndex);
});
}
private void loadText( int index){
BannerText bannerText = steps.get(index).bannerInstructions().get(0).primary();
InstructionLoader loader = new InstructionLoader(tv_step, bannerText );
loader.loadInstruction();
String text = tv_step.getText().toString();
String modifier = bannerText.modifier();
String directionArrow = getDirectionArrow(text, modifier);
if(!directionArrow.equals(""))
tv_step.setText(directionArrow + text);
tv_step.append(" " + getDistanceStr(steps.get(index).distance()));
Log.d("Debugging modifier", bannerText.toJson());
}
#Override
public void onNavigationReady(boolean isRunning) {
DirectionsRoute directionsRoute = (DirectionsRoute) getIntent().getSerializableExtra("route");
NavigationViewOptions options = NavigationViewOptions.builder()
.directionsRoute(directionsRoute)
.shouldSimulateRoute(false)
.milestoneEventListener(this)
.build();
navigationView.startNavigation(options);
}
#Override
public void onMilestoneEvent(RouteProgress routeProgress, String instruction, Milestone milestone) {
try {
if (milestone instanceof BannerInstructionMilestone) {
BannerText primaryInstruction = ((BannerInstructionMilestone) milestone).getBannerInstructions().primary();
primaryInstruction.text();
InstructionLoader loader = new InstructionLoader(myBanner, primaryInstruction);
loader.loadInstruction();
String text = myBanner.getText().toString();
String modifier = primaryInstruction.modifier();
String directionArrow = getDirectionArrow(text, modifier);
if(!directionArrow.equals(""))
myBanner.setText(directionArrow + text);
double distance = routeProgress.currentLegProgress().currentStep().distance();
String distanceStr = getDistanceStr(distance);
String milestoneString = myBanner.getText().toString() + distanceStr;
}
}catch (Exception e){
e.printStackTrace();
}
}
private String getDirectionArrow(String text, String modifier){
Log.e("Debugging", text + " " + modifier);
if (text.contains("right") || modifier.contains("right"))
return "> ";
else if (text.contains("left") || modifier.contains("left"))
return "< ";
else if (text.contains("straight") || modifier.contains("straight"))
return "^ ";
return "";
}
private String getDistanceStr(double distance){
if(distance > 1000)
return " " + formatAmount(distance/1000) + " km";
else return " " + distance + " m";
}
#Override
public void onStart() {
super.onStart();
navigationView.onStart();
}
#Override
public void onResume() {
super.onResume();
navigationView.onResume();
}
#Override
public void onLowMemory() {
super.onLowMemory();
navigationView.onLowMemory();
}
#Override
public void onBackPressed() {
if (!navigationView.onBackPressed()) {
super.onBackPressed();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
navigationView.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
navigationView.onRestoreInstanceState(savedInstanceState);
}
#Override
public void onPause() {
super.onPause();
navigationView.onPause();
}
#Override
public void onStop() {
super.onStop();
navigationView.onStop();
}
#Override
protected void onDestroy() {
super.onDestroy();
navigationView.onDestroy();
}
public static String formatAmount(Double str){
BigDecimal bd = new BigDecimal(str);
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
return bd.toString();
}
}
activity_navigations.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="talha.niazi.hudlitenav.MainActivity"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:id="#+id/dummyBanner"
android:background="#color/design_default_color_primary"
android:textColor="#color/mapboxWhite"
android:padding="10dp"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="match_parent"
android:background="#color/button_red"
android:id="#+id/ll_nav"
android:padding="15dp"
android:layout_height="wrap_content">
<ImageView
android:layout_width="30sp"
android:tint="#color/white_color"
android:id="#+id/iv_previous"
mapbox:srcCompat="#drawable/previous"
android:layout_height="30sp" />
<TextView
android:layout_width="wrap_content"
android:textColor="#color/white_color"
android:layout_marginStart="10sp"
android:textStyle="bold"
android:layout_marginEnd="10sp"
android:layout_centerVertical="true"
android:id="#+id/tv_step"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content" />
<ImageView
android:layout_width="30sp"
android:layout_alignParentEnd="true"
android:id="#+id/iv_next"
android:tint="#color/white_color"
mapbox:srcCompat="#drawable/next"
android:layout_height="30sp" />
</RelativeLayout>
<com.mapbox.services.android.navigation.ui.v5.NavigationView
android:id="#+id/navigationView"
android:layout_below="#id/ll_nav"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
It would be great if you can help me to fix this weird issue.
Can you try to set the content theme
super.onCreate(savedInstanceState)
setTheme(R.style.Theme_AppCompat_Light_NoActionBar);
before setting the contentView?
Also where did you set the style of NavigationView? You can do that in the layout XML file:
<com.mapbox.services.android.navigation.ui.v5.NavigationView
android:id="#+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navigationDarkTheme="#style/CustomNavigationView"
app:navigationLightTheme="#style/CustomNavigationView"
app:navigationViewMapStyle="mapbox://styles/StyleURL"/>
Please use your custom styleURL.
Please let me know if it helped!
Solution in Kotlin
For more information
This issue has been resolved here Can’t start turn-by-turn navigation within custom NavigationViewActivity/NavigationViewFragment #1524
First I updated the SDK version from 0.13.0 to 0.23.0
implementation 'com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.23.0'
The dependency will transitively bring in the Maps SDK and the core navigation libraries. This helps prevents conflicts.
In project root build.gradle don't forget to add
maven { url 'https://mapbox.bintray.com/mapbox' }
in fragment_navigation.xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="NavigationViewFragment">
<com.mapbox.navigation.ui.NavigationView
android:id="#+id/navigationView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
In NavigationViewFragment
originPoint and destinationPoint is variable type Point.fromLngLat(longitude,latitude)
class NavigationViewFragment : Fragment(), OnNavigationReadyCallback, NavigationListener {
private lateinit var navigationView: NavigationView
var directionsRoute: DirectionsRoute? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
.....
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navigationView = view.findViewById(R.id.navigationView) as NavigationView
navigationView.onCreate(savedInstanceState)
val initialPosition = CameraPosition.Builder()
.target(LatLng(originPoint.longitude(), originPoint.latitude()))
.zoom(18.0)
.build()
navigationView.initialize(this, initialPosition)
}
override fun onNavigationReady(isRunning: Boolean) {
val origin = Point.fromLngLat(originPoint.longitude() , originPoint.latitude())
val destination = Point.fromLngLat(destinationPoint.longitude(), destinationPoint.latitude())
calculateRoute(origin, destination)
}
override fun onCancelNavigation() {
// Do something
}
override fun onNavigationFinished() {
// Do something
}
override fun onNavigationRunning() {
// Do something
}
private fun calculateRoute(origin: Point , destination: Point) {
NavigationRoute.builder(this.context)
.accessToken(Mapbox.getAccessToken()!!)
.origin(origin)
.destination(destination)
.build()
.getRoute( object : Callback<DirectionsResponse> { //import retrofit2.Callback
// Send request to Direction API
override fun onFailure(call: Call<DirectionsResponse>? , t: Throwable?) {
}
override fun onResponse(call: Call<DirectionsResponse>? ,
response: Response<DirectionsResponse>?) {
if (response?.body() == null || response.body()?.routes()?.size!! < 1) {
return
}
directionsRoute = response.body()!!.routes()[0]
startNavigation()
}
})
}
private fun startNavigation() {
if (directionsRoute == null) return
val options = NavigationViewOptions.builder()
.directionsRoute(directionsRoute)
.shouldSimulateRoute(true)
.navigationListener(this)
.build()
// start camera zooms to the beginning of the route
navigationView.startCamera(directionsRoute)
navigationView.startNavigation(options)
}
}
I want to generate a PDF, but first I need to create an image from a LineChart (MPAndroidChart library) without displaying it in an activity.
I've followed this tutorial http://android-crap.blogspot.com/2013/02/create-bitmap-from-layoutview.html, and I've modified the code to my own requirement:
private void createLineChart(double frequency) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout view = new RelativeLayout(activity);
inflater.inflate(R.layout.line_chart_layout, view, true);
LineChart lc = view.findViewById(R.id.lncMain);
lc.setData(createLineData(frequency));
lc.invalidate();
view.setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
String filename = "graph.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
try {
FileOutputStream out = new FileOutputStream(dest);
b.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, filename);
}
The activity variable is an instance of AppCompatActivity. The R.layout.line_chart_layout's content:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layParent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<com.github.mikephil.charting.charts.LineChart
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lncMain"
android:orientation="horizontal"
>
</com.github.mikephil.charting.charts.LineChart>
</RelativeLayout>
Once the app is executed I get an image file called graph.png, but its content does not relfect the desire plot:
I have tried different values for view.setLayoutParams, view.layout, but it does not work... Some suggestions, please!
My guess is that graph.png looks so jumbled because the LineChart is never really added to the Activity's layout and so its "real size" is not calculated correctly. I know that you don't want to display the chart to the users but one can achieve that e.g. by setting the View invisible.
So here's my version:
public class MainActivity extends AppCompatActivity {
private LineChart lc;
private RelativeLayout view;
private static final String TAG = "LCTP Main";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
if(Build.VERSION.SDK_INT > 22 && (checkSelfPermission(WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED)) {
requestPermissions(new String[]{READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE}, 13);
}
else {
createLineChart(440.0);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 13){
boolean ok = true;
int length = permissions.length;
for (int i = 0; i < length; i++) {
String permission = permissions[i];
if(grantResults[i] != PERMISSION_GRANTED){
Log.d(TAG, "onRequestPermissionsResult: missing permission " + permission);
ok = false;
}
}
if(ok){
createLineChart(220);
}
}
}
private void createLineChart(double frequency) {
if(lc == null){
view = findViewById(R.id.layParent);
lc = findViewById(R.id.lncMain);
}
lc.setData(createLineData(frequency));
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(c);
String filename = "graph.png";
File sd = Environment.getExternalStorageDirectory();
File dest = new File(sd, filename);
try {
FileOutputStream out = new FileOutputStream(dest);
b.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.i(TAG, filename);
}
});
lc.invalidate();
}
private LineData createLineData(double frequency) {
List<Entry> yVals = new ArrayList<>();
for(int i = 0; i < frequency; i = i + 10){
yVals.add(new Entry(i, (float)Math.sin(i*i)));
}
ILineDataSet lineDataSet = new LineDataSet(yVals, "LabelString");
LineData lineData = new LineData(lineDataSet);
return lineData;
}
}
activity_main.xml:
<LinearLayout
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"
android:padding="24dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Hello World!"/>
<include
layout="#layout/line_chart_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"/>
</LinearLayout>
The resulting png:
I have an activity which generates a scrollable list (let's say a column) of programmatically created buttons from a List which is the result of an sqlite table read and my problem is that as the List is growing (and so the number of buttons) the initial painting of the screen is becoming slow (at the moment is taking 3 seconds with 50 buttons to draw) so I'm looking for a solution to this.
At first I thought of using a thread (runnable, handler or whatever is best), let's say creating a new thread inside the For which iterates over the list but it's not working (or at least I'm not being able to make it to work) so my question is the next:
Starting from a List<> which is the most appropiate way to create a big set of scrollable buttons so users doesn't have such delay when accesing the screen.
Paginating could be an option, but I'd like to know about other possibilities first and leave that as a last resource.
Thanks, and below is my code.
public static void createButtons(LinearLayout llContainer,
List<TestType> TestTypes, List<Test> Tests,
int buttonFontSize) {
Context oContext = llContainer.getContext();
String strTheme = TMAppearance.getThemeFromPreferences(oContext);
testMe = ((ApplicationConfiguration)oContext.getApplicationContext());
int callerActivity = TestTypes!=null ? 2 : 1;
if (TestTypes!=null || Tests!=null) {
int lCols = strTheme.equals(testMe.theme_vivid) ? 1 : 2;
//int sourceElementIndex = 0;
int originListSize = calculateOriginalListSize(callerActivity, TestTypes, Tests);
int lRows = (int) Math.ceil((double)originListSize/lCols);
List<String> aStartColors = TMUtils_ThemeVivid.generateStartColorArray(lRows, oContext);
List<String> aEndColors = TMUtils_ThemeVivid.generateEndColorArray(lRows, oContext);
for (i = 0; i < lRows; i++) {
LinearLayout outerButtonLayout = generateOuterButtonLayout(oContext);
for (j = 0; j < lCols; j++) {
final Thread r = new Thread() {
public void run() {
LinearLayout innerButtonLayout = generateInnerButtonLayout(oContext);
outerButtonLayout.addView(innerButtonLayout, j);
if (sourceElementIndex<originListSize){
final TMButton oButton = new TMButton(oContext);
if (callerActivity==1) { //testMenu
setTestMenuButtonSettings(oButton, sourceElementIndex, Tests);
} else {
if (callerActivity==2) { //testTypeMenu
setTestTypeMenuButtonSettings(oButton, sourceElementIndex, TestTypes);
}
}
if (strTheme.equals(testMe.theme_vivid)){
oButton.fontSize = buttonFontSize;
oButton.gradientStartColor = aStartColors.get(i);
oButton.gradientEndColor = aEndColors.get(i);
}else{
if (strTheme.equals(testMe.theme_purple)){
oButton.gradientStartColor = testMe.btnStartColor_purple;
oButton.gradientEndColor = testMe.btnEndColor_purple;
}
}
configureButton(oButton, callerActivity);
oButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Context oContext = v.getContext();
TMButton oButton = (TMButton) v;
int callerActivity = Integer.valueOf(v.getTag().toString().split("#")[0]);
String sourceId = String.valueOf(v.getTag().toString().split("#")[1]);
if(event.getAction() == MotionEvent.ACTION_DOWN) { //pressed
setButtonPressed(oButton);
TMSound.playButtonSound(oContext);
} else if (event.getAction() == MotionEvent.ACTION_UP) { //released
setButtonReleased(oButton);
startTargetActivity(callerActivity, sourceId, oContext);
}
return true;
}
});
TMAppearance.doButtonAnimation(oContext, oButton, i);
innerButtonLayout.addView(oButton);
sourceElementIndex++;
}
}
};
r.run();
}
llContainer.addView(outerButtonLayout);
}
}
}
0X0nosugar is correct. A RecycleView will provide better performance, but many beginners have more difficulty implementing it and with only 50 buttons performance shouldn't really be an issue. And although I generally like to abide by the rule 'Use the best available solution' I think it is still appropriate to learn how to implement the ListView. So...
You will need to create a custom adapter:
public class MyListDataAdapter extends ArrayAdapter<MyListData> {
private static final String TAG = "MyListDataAdapter";
public MyListDataAdapter(Context context, ArrayList<MyListData> data) {
super(context, 0, data);
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
final MyListData data = getItem(position);
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.edit_list_item, parent, false);
}
// Add a TextView if you need one
final TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
Button btnEditTicketHolder = (Button) convertView.findViewById(R.id.btnEdit);
btnEditTicketHolder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
long userId = data.getUserId();
String fName = data.getFirstName();
Intent intent = new Intent(getContext(), EditActivity.class);
intent.putExtra("userId", userId);
intent.putExtra("fName", fName);
getContext().startActivity(intent);
}
});
String name = data.getFirstName();
tvName.setText(name);
return convertView;
}
}
Now you need your MyListData class to hold the data:
public class MyListData {
// Add more as you need
private long userId;
private String firstName;
public MyListData(){
}
public void setFirstName(String name){ this.firstName = name; }
public void setUserId(long id){ this.userId = id; }
public String getFirstName(){ return this.firstName; }
public long getUserId(){ return this.userId; }
}
Your custom ListView layout could look something like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
<TextView
android:id="#+id/tvName"
android:text="With Whom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
>
<Button
android:id="#+id/btnEdit"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:text="Edit"
android:backgroundTint="#color/colorAccent"
android:focusable="false"
/>
</LinearLayout>
</RelativeLayout>
In your Activity (eg. in the onCreate() method) where the ListView you will need to populate the data for the ListView. This should not be done on the UI Thread
ArrayList<MyListData> arrayListData = new ArrayList<MyListData>();
MyListDataAdapter adapter = new MyListDataAdapter(this, arrayListData);
for (MyListData g : result) {
adapter.add(g);
}
mLstMy.setAdapter(adapter);
Also in the activity where the ListView is to be maintained set up some onClick event handlers if you need them:
(I find that one of the small advantages of the ListView is that the onClick event is easier it implement than in the RecycleView)
mMyLst = (ListView) findViewById(lstMy);
mMyLst.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long l) {
MyListData data = (MyListData) parent.getItemAtPosition(position);
selectedName = data.getName();
Intent intent = new Intent(ShowListDataActivity.this, MainActivity.class);
startActivity(intent);
}
});
mMyLst.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
MyListData data = (MyistData) adapterView.getItemAtPosition(i);
selectedName = data.getFirstName();
selectedTicketPosition = i;
// removeValue is my own method for removing an entry from the
// list MyListData and then call adapter.notifyDataSetChanged();
removeValue(i);
return true;
}
});
I have 3 tabs that extent fragment. the second fragment (extends fragment implements locationListener) have a map with bus station markers (works perfect).I want from first tab via a button open the second fragment in order to get the position of marker(latlng). My problem is that i can not do that with intent (startActivityforresult) because is not an activity. Could you please anyone help me with this issue?
firstfragment.class
public class FirstTab extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.first, container, false);
Button btnFrom;
Button btnTo;
// Getting reference to Buttons From&To
btnFrom = ( Button ) view.findViewById(R.id.btn_from);
btnTo = ( Button ) view.findViewById(R.id.btn_to);
// click listener on Buttons From
btnFrom.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// move to secondfragment
}
});
// click listener on Buttons To
btnTo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// move to secondfragment
}
});
return view;
}
}
first.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="14dp"
android:layout_marginTop="25dp"
android:text="Destination from:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/btn_showroute"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:text="Show My Route" />
<Button
android:id="#+id/btn_to"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_below="#+id/btnSpeak1"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="#string/str_btn_to" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_centerVertical="true"
android:text="Destination To:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/btn_from"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_alignLeft="#+id/btn_to"
android:layout_below="#+id/btnSpeak"
android:layout_marginTop="29dp"
android:text="#string/str_btn_from" />
SecondTab.class
public class SecondTab extends Fragment implements LocationListener{
GoogleMap mGoogleMap;
Spinner mSprPlaceType;
Spinner mSprRadius;
String[] mPlaceType=null;
String[] mPlaceTypeName=null;
String[] mRadius=null;
String[] mRadiusType=null;
double mLatitude=0;
double mLongitude=0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.second, container, false);
// Array of place types
mPlaceType = getResources().getStringArray(R.array.place_type);
// Array of radius
mRadius = getResources().getStringArray(R.array.radius);
mRadiusType = getResources().getStringArray(R.array.radius_type);
// Array of place type names
mPlaceTypeName = getResources().getStringArray(R.array.place_type_name);
// Creating an array adapter with an array of Place types
// to populate the spinner
ArrayAdapter<?> adapter = new ArrayAdapter<Object>(getActivity(), android.R.layout.simple_spinner_dropdown_item, mPlaceTypeName);
ArrayAdapter<?> radapter = new ArrayAdapter<Object>(getActivity(), android.R.layout.simple_spinner_dropdown_item, mRadius);
// Getting reference to the Spinner
mSprPlaceType = (Spinner) view.findViewById(R.id.spr_place_type);
mSprRadius = (Spinner) view.findViewById(R.id.spr_radius);
// Setting adapter on Spinner to set place types
mSprPlaceType.setAdapter(adapter);
mSprRadius.setAdapter(radapter);
Button btnFind;
// Getting reference to Find Button
btnFind = ( Button ) view.findViewById(R.id.btn_find);
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(), requestCode);
dialog.show();
}else { // Google Play Services are available
// Getting reference to the SupportMapFragment
SupportMapFragment fragment = ( SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
// Getting Google Map
mGoogleMap = fragment.getMap();
// Enabling MyLocation in Google Map
mGoogleMap.setMyLocationEnabled(true);
// Getting LocationManager object from System Service LOCATION_SERVICE
// LocationManager locationManager = (LocationManager)
getSystemService(LOCATION_SERVICE);
LocationManager locationManager = (LocationManager)
getActivity().getSystemService(Context.LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location From GPS
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 20000, 0, this);
// Setting click event lister for the find button
btnFind.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int selectedPosition = mSprRadius.getSelectedItemPosition();
String type = mRadiusType[selectedPosition];
StringBuilder sb = new
StringBuilder("https://maps.googleapis.com/maps/api/
place/nearbysearch/json?");
sb.append("location="+mLatitude+","+mLongitude);
sb.append("&radius="+type);
sb.append("&types=bus_station");
sb.append("&sensor=true");
sb.append("&key=APIKEY");
// Creating a new non-ui thread task to download json data
PlacesTask placesTask = new PlacesTask();
// Invokes the "doInBackground()" method of the class
placesTask.execute(sb.toString());
}
});
}
return view;
}
/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new
InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
urlConnection.disconnect();
}
return data;
}
/** A class, to download Google Places */
private class PlacesTask extends AsyncTask<String, Integer, String>{
String data = null;
// Invoked by execute() method of this object
#Override
protected String doInBackground(String... url) {
try{
data = downloadUrl(url[0]);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(String result){
ParserTask parserTask = new ParserTask();
// Start parsing the Google places in JSON format
// Invokes the "doInBackground()" method of the class ParseTask
parserTask.execute(result);
}
}
/** A class to parse the Google Places in JSON format */
private class ParserTask extends AsyncTask<String, Integer,
List<HashMap<String,String>>>{
JSONObject jObject;
// Invoked by execute() method of this object
#Override
protected List<HashMap<String,String>> doInBackground(String...jsonData)
{
List<HashMap<String, String>> places = null;
PlaceJSONParser placeJsonParser = new PlaceJSONParser();
try{
jObject = new JSONObject(jsonData[0]);
/** Getting the parsed data as a List construct */
places = placeJsonParser.parse(jObject);
}catch(Exception e){
Log.d("Exception",e.toString());
}
return places;
}
// Executed after the complete execution of doInBackground() method
#Override
protected void onPostExecute(List<HashMap<String,String>> list){
// Clears all the existing markers
mGoogleMap.clear();
for(int i=0;i<list.size();i++){
// Creating a marker
MarkerOptions markerOptions = new MarkerOptions();
// Getting a place from the places list
HashMap<String, String> hmPlace = list.get(i);
// Getting latitude of the place
double lat = Double.parseDouble(hmPlace.get("lat"));
// Getting longitude of the place
double lng = Double.parseDouble(hmPlace.get("lng"));
// Getting name
String name = hmPlace.get("place_name");
// Getting vicinity
String vicinity = hmPlace.get("vicinity");
LatLng latLng = new LatLng(lat, lng);
// Setting the position for the marker
markerOptions.position(latLng);
// LatLng getmarker = markerOptions.getPosition();
// Setting the title for the marker.
//This will be displayed on taping the marker
markerOptions.title(name + " : " + vicinity);
// Placing a marker on the touched position
mGoogleMap.addMarker(markerOptions);
}
}
}
#Override
public void onLocationChanged(Location location) {
mLatitude = location.getLatitude();
mLongitude = location.getLongitude();
LatLng latLng = new LatLng(mLatitude, mLongitude);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(16));
}
public void setResult(int i, Intent returnIntent) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
second.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="#+id/spr_place_type"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_alignParentTop="true" />
<Spinner
android:id="#+id/spr_radius"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_toRightOf="#id/spr_place_type"
android:layout_alignParentTop="true" />
<Button
android:id="#+id/btn_find"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="#id/spr_radius"
android:text="#string/str_btn_find" />
<fragment
android:id="#+id/map"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/spr_place_type"
class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>
Tabadapter
public class Tabsadapter extends FragmentStatePagerAdapter{
private int TOTAL_TABS = 3;
public Tabsadapter(FragmentManager fm) {
super(fm);
// TODO Auto-generated constructor stub
}
#Override
public Fragment getItem(int index) {
// TODO Auto-generated method stub
switch (index) {
case 0:
return new RouteFragmentTab();
case 1:
return new FindRouteFragmentTab();
case 2:
return new MapRouteFragmentTab();
}
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return TOTAL_TABS;
}
}
You can use the replace() method on your fragment to replace the current fragment with another.
i.e.: replace(YourNewFragment.newInstance());
OR
If you don't want to actually replace the fragment, you can change tabs programmatically to the tab you want to display. If you are using a ViewPager this can be done by calling yourViewPager.setCurrentItem(indexToSet).
Let me know if this helps, or if you have any other questions in regard to my answer!
I was facing the same issue and i easily solved it by calling viewpager from the firstFragment class, and then easily setting the viewpager's current item to the index of the tab you want.
here's the code which i placed in the onClick method of the first tab fragment for me to go the third tab fragment;
ViewPager viewPager = getActivity().findViewById(R.id.simpleViewPager);
viewPager.setCurrentItem(2);
My answer might be late, but i hope it helps anyone else who might meet this challenge.
So, I have scoured the interwebs and I cannot find a solution for this based on other people's experiences, so I am posting this issue. (Please note that this is my 1st android app experience and I am debugging / updating an existing app.)
When I implement my custom NotesListAdapter (extends BaseAdapter) on the ListView, mListNotesView (mListNotesView.setAdapter(this)), and load the data into the ArrayList mNoteList, the getView function is not being called. Also, I found that mListNotesView.setBackgroundResource is not chaning the background of the control, either. I have a similar implementation on a previous activity that works exactly correct. When I copied over the class and changed it to handle my ArrayList, it broke. I have getCount returning the ArrayList size(), which is not 0, and getItemId returns position. I have a feeling it may be my XML or my setup because it's acting like the ListView is not visible. I am perplexed. How do I get the ListView to show? Anything inside of the getView has not been reached so it may be buggy.
ViewTicketOrderActivity (Some parts ommitted for size)
public class ViewTicketOrderActivity extends Activity {
MySQLDatabase myDataBase;
Ticket mTicket;
public ArrayList<Notes> mNotes = new ArrayList<Notes>();
String mErrorString;
Button mAddUpdateButton;
Button mAcceptButton;
//Button mViewNotesButton;
NotesListAdapter mNotesListAdapter;
static final int ERROR_DIALOG = 0;
static final int SUCCESS_DIALOG = 1;
static final int COMPLETED_DIALOG = 2;
static final int RESTART_DIALOG = 3;
static final int LOADING = 0;
static final int LOAD_ERROR = 1;
static final int LOADED = 4;
static final String TICKET_EXTRA = "ticket_extra";
static final String TAG = "ViewTicketOrderActivity";
private static final boolean gDebugLog = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewticketorder);
Activity context = this;
String theTitle = "Sundance Ticket Order";
theTitle += (MySQLDatabase.TESTING == true) ? " (DEV SERVER)" : " (LIVE)";
setTitle(theTitle);
myDataBase = MySQLDatabase.getMySQLDatabase(this);
if (gDebugLog) {
DebugLogger.logString(TAG, ".onCreate");
}
mNotesListAdapter = new NotesListAdapter(context, R.id.note_list);
Log.d(this.toString(),this.mNotesListAdapter.toString());
}
private class NotesListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<Notes> mNoteList;
private ListView mListNotesView;
private Activity mActivity;
int mState = LOADING;
String mErrorMessage;
private NotesListAdapter(Activity context, int listViewID) {
mActivity = context;
mNoteList = new ArrayList<Notes>();
mInflater = LayoutInflater.from(context);
mListNotesView = (ListView)context.findViewById(listViewID);
mListNotesView.setBackgroundResource(R.color.emergency_red);
mListNotesView.setAdapter(this);
Log.d(mListNotesView.toString(), String.valueOf(mListNotesView.getCount()));
this.notifyDataSetChanged();
//mListNotesView.setVisibility(View.VISIBLE);
}
void setLoading()
{
mState = LOADING;
this.notifyDataSetChanged();
}
void setLoadError(String errorString)
{
mState = LOAD_ERROR;
mErrorMessage = errorString;
this.notifyDataSetChanged();
}
void setNoteList(ArrayList<Notes> inNotes)
{
mState = LOADED;
mNoteList.clear();
mNoteList.addAll(inNotes);
Log.d("SetNoteList", "TRUE " + inNotes);
//mNoteList = mNotes;
this.notifyDataSetChanged();
}
/**
* Use the array index as a unique id.
*
* #see android.widget.ListAdapter#getItemId(int)
*/
#Override
public long getItemId(int position) {
return position;
}
public int getCount(){
if (mState == LOADED) {
Log.d("getCount",String.valueOf(mNoteList.size()));
return mNoteList.size();
} else {
return 0;
}
}
/**
* Make a view to hold each row.
*
* #see android.widget.ListAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
Log.d("getView",this.toString());
if (mState == LOADED) {
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there
// is no need
// to reinflate it. We only inflate a new View when the
// convertView supplied
// by ListView is null.
Notes note = this.getItem(position);
if (convertView == null) {
/*if (ticket.emergency())
{
convertView = mInflater.inflate(R.layout.emergency_ticket_list_item_opt,
null);
}
else
{
convertView = mInflater.inflate(R.layout.ticket_list_item,
null);
}*/
convertView = mInflater.inflate(R.layout.noteslist_item,
null);
// Creates a ViewHolder and store references to the two
// children views
// we want to bind data to.
holder = new ViewHolder();
holder.noteText = (TextView) convertView
.findViewById(R.id.text_note);
holder.dateText = (TextView) convertView
.findViewById(R.id.text_note_date);
holder.createByText = (TextView) convertView
.findViewById(R.id.text_note_by);
holder.createByIDText = (TextView) convertView
.findViewById(R.id.text_note_by_id);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the
// TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.noteText.setText(note.note());
holder.dateText.setText(note.date());
holder.createByText.setText(note.createBy());
holder.createByIDText.setText(note.employeeID());
if(!mTicket.employeeID().equals(note.employeeID())){
convertView.setBackgroundResource(R.drawable.solid_purple);
}
} else if (mState == LOADING ) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.loading_view,
null);
}
TextView messageText = (TextView)convertView.findViewById(R.id.message);
messageText.setText("Loading tickets");
} else if (mState == LOAD_ERROR) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.load_error_view,
null);
}
TextView messageText = (TextView)convertView.findViewById(R.id.message);
messageText.setText("Error loading tickets");
String errorString = mErrorMessage != null ? mErrorMessage : "";
TextView errorText = (TextView)convertView.findViewById(R.id.errorText);
errorText.setText(errorString);
}
return convertView;
}
class ViewHolder {
TextView noteText;
TextView dateText;
TextView createByText;
TextView createByIDText;
}
//#Override
/*public int getCount() {
*//*if (mState == LOADED) {
*//*
Log.d("getCount mState " + mState,String.valueOf(mNoteList.size())+", "+String.valueOf(mNotes.size()));
return mNoteList.size();
*//*} else {
Log.d("getCount mState " + mState,"0");
return 0;
}*//*
}*/
#Override
public Notes getItem(int position) {
Log.d("getItem",mNoteList.get(position).toString());
return mNoteList.get(position);
}
#Override
public int getItemViewType (int position) {
int result = mState;
Log.d("getItemId",String.valueOf(position));
return result;
}
#Override
public int getViewTypeCount ()
{
return 4;
}
}
protected void onResume() {
super.onResume();
Bundle extras = getIntent().getExtras();
if(extras !=null)
{
mTicket = (Ticket)extras.getSerializable(TICKET_EXTRA);
}
else
{
mTicket = new Ticket();
}
if (mTicket.emergency())
{
setContentView(R.layout.view_emergency_ticketorder);
}
else
{
setContentView(R.layout.viewticketorder);
}
if (gDebugLog)
{
DebugLogger.logString(TAG, ".onResume mTicket " + mTicket);
}
TicketCheckService.clearNotificationForNewTicket(mTicket);
new GetTicketTask().execute();
new GetNotesTask().execute();
updateDisplayedTicket();
}
private void updateDisplayedTicket() {
mAddUpdateButton = (Button)findViewById(R.id.addUpdateButton);
mAcceptButton = (Button)findViewById(R.id.acceptButton);
//mViewNotesButton = (Button)findViewById(R.id.viewNotesButton);
String ticketStatus = myDataBase.getDescriptionStringForStatusString(mTicket.status());
if(ticketStatus == "Job Rejected") {
mAddUpdateButton.setText("Restart Job");
} else {
mAddUpdateButton.setText("Add Update");
}
if(ticketStatus == "Requested") {
mAcceptButton.setText("Accept");
} else if(ticketStatus != "Requested") {
mAcceptButton.setText("Back");
}
//mViewNotesButton.setText(R.string.viewNotes);
TextView idText = (TextView)findViewById(R.id.textTicketID);
idText.setText(mTicket.id());
//TextView descriptionText = (TextView)findViewById(R.id.textDescription);
//descriptionText.setText(mTicket.description());
TextView titleText = (TextView)findViewById(R.id.textTitle);
titleText.setText(mTicket.title());
TextView storeIDText = (TextView)findViewById(R.id.textStoreID);
storeIDText.setText(mTicket.store());
String formatPhone;
TextView storePhoneText = (TextView)findViewById(R.id.textStorePhone);
if(mTicket.phoneNo().isEmpty()){
formatPhone = "NO PHONE NO.";
} else {
storePhoneText = (TextView) findViewById(R.id.textStorePhone);
formatPhone = mTicket.phoneNo().replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)$2-$3");
storePhoneText.setOnClickListener(new CallClickListener(mTicket.phoneNo()));
}
storePhoneText.setText(formatPhone);
TextView categoryText = (TextView)findViewById(R.id.textCategory);
String categoryDescription = MySQLDatabase.getDescriptionStringForCategoryString(mTicket.category());
categoryText.setText(categoryDescription);
if(ticketStatus == "Completed Pending") {
showDialog(COMPLETED_DIALOG);
}
}
public void onClickAccept(View v) {
try {
boolean maint = myDataBase.getSystemMaintStatus();
if(maint) {
setLoadError("The phone app is down for maintenance.");
return;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mAcceptButton.getText() =="Accept") {
mAddUpdateButton.setEnabled(false);
mAcceptButton.setEnabled(false);
new AcceptTicketTask().execute();
} else {
finish();
}
}
public void onClickAddUpdate(View v) {
try {
boolean maint = myDataBase.getSystemMaintStatus();
if(maint) {
setLoadError("The phone app is down for maintenance.");
return;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(mAddUpdateButton.getText() =="Add Update") {
Intent i = new Intent(this, UpdateTicketActivity.class);
i.putExtra(UpdateTicketActivity.TICKET_EXTRA, mTicket);
startActivity(i);
} else if(mAddUpdateButton.getText() =="Restart Job") {
mAddUpdateButton.setEnabled(false);
mAcceptButton.setEnabled(false);
new RestartTicketTask().execute();
}
}
private class AcceptTicketTask extends AsyncTask<Void, Integer, String>
{
protected String doInBackground(Void... parent) {
mErrorString = null;
String result = null;
String updateTime = DateFormat.getDateTimeInstance().format(new Date(0));
try {
boolean success = myDataBase.updateTicket(mTicket.id(), mTicket.employeeID(), mTicket.description(), "1", updateTime, null);
if (!success)
{
result = "Could not update Ticket";
}
} catch (IOException e) {
// TODO Auto-generated catch block
result = "Could not update Ticket - " + e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(String errorString) {
if (null != errorString) {
mErrorString = errorString;
showDialog(ERROR_DIALOG);
} else {
showDialog(SUCCESS_DIALOG);
mAcceptButton.setText("Back");
}
mAddUpdateButton.setEnabled(true);
mAcceptButton.setEnabled(true);
}
}
private class RestartTicketTask extends AsyncTask<Void, Integer, String>
{
protected String doInBackground(Void... parent) {
mErrorString = null;
String result = null;
String updateTime = DateFormat.getDateTimeInstance().format(new Date(0));
try {
boolean success = myDataBase.updateTicket(mTicket.id(), mTicket.employeeID(), mTicket.description(), "7", updateTime, null);
if (!success)
{
result = "Could not update Ticket";
}
} catch (IOException e) {
// TODO Auto-generated catch block
result = "Could not update Ticket - " + e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(String errorString)
{
if (null != errorString) {
mErrorString = errorString;
showDialog(ERROR_DIALOG);
} else {
showDialog(RESTART_DIALOG);
mAcceptButton.setText("Done");
mAddUpdateButton.setText("Add Update");
}
mAddUpdateButton.setEnabled(true);
mAcceptButton.setEnabled(true);
}
}
private class GetTicketTask extends AsyncTask<Void, Integer, Ticket>
{
String mError = null;
protected Ticket doInBackground(Void... parent) {
Ticket result = null;
try {
result = myDataBase.getTicketWithID(mTicket.id(), mTicket.employeeID());
} catch (IOException e) {
// TODO Auto-generated catch block
mError = e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(Ticket result)
{
if (null != result) {
mTicket = result;
} else {
setLoadError(mError);
}
}
}
private class GetNotesTask extends AsyncTask<Void, Integer, ArrayList<Notes>> {
String mError = null;
protected ArrayList<Notes> doInBackground(Void... parent) {
ArrayList<Notes> result = new ArrayList<Notes>();
try {
result = myDataBase.getTicketNotes(mTicket.id());
} catch (IOException e) {
// TODO Auto-generated catch block
myDataBase.debugLog("Error caught" + e);
mError = e.getLocalizedMessage();
e.printStackTrace();
}
return result;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(ArrayList<Notes> result) {
if (null != result) {
Log.d("Result", result.toString());
mNotes = result;
} else {
Log.d("SetNoteList","FALSE");
mNotesListAdapter.setLoadError(mError);
}
}
}
private void updateDisplayedNotes(){
ArrayList<Notes> newNotes = mNotes;
if(newNotes != null) {
mNotesListAdapter.setNoteList(newNotes);
}
}
/*private class updateDisplayedNotes extends AsyncTask<Void, Integer, ArrayList<Notes>> {
public ArrayList<Notes> newNotes = new ArrayList<Notes>();
public updateDisplayedNotes(){
super();
Log.d(this.toString(), "Updating");
}
protected ArrayList<Notes> doInBackground(Void... parent) {
Log.d(this.toString(), "Background Task");
for (Notes note : mNotes) {
Log.d(this.toString(),note.toString());
if(note != null) {
Log.d(this.toString(), "Note Added");
newNotes.add(note);
}
}
return newNotes;
}
protected void onPostExecute(ArrayList<Notes> newNotes)
{
if(newNotes != null) {
mNotes.clear();
mNotes.addAll(newNotes);
mNotesListAdapter.setNoteList(mNotes);
}
}
}*/
void setLoadError(String error) {
setContentView(R.layout.load_error_view);
TextView messageText = (TextView)findViewById(R.id.message);
messageText.setText("Error loading ticket");
String errorString = error != null ? error : "";
TextView errorText = (TextView)findViewById(R.id.errorText);
errorText.setText(errorString);
finish();
}
}
viewticketorder.xml (where note_list is)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:background="#drawable/background"
android:orientation="vertical"
tools:context=".ViewTicketOrderActivity"
tools:ignore="HardcodedText" >
<TextView
android:id="#+id/textTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:text="#string/loadingTicket"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/white_color"
android:textSize="20dp"
android:textIsSelectable="true"
android:background="#drawable/title_transparent_bg"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:paddingTop="2dp"
android:paddingLeft="10dp"
android:text="#string/ticketID"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/textTicketID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="#color/white_color"
android:textIsSelectable="true"/>
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="3dp"
android:paddingTop="2dp"
android:text="#string/storeID"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText" />
<TextView
android:id="#+id/textStoreID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="#color/white_color"
android:textIsSelectable="true"/>
<TextView
android:id="#+id/textStorePhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:focusable="true"
android:textColor="#color/white_color"
android:textIsSelectable="true"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/TextView05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:paddingTop="2dp"
android:text="#string/category"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/textCategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/white_color"
android:focusable="true"
android:textIsSelectable="true"/>
</LinearLayout>
<ListView
android:id="#+id/note_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
android:divider="#drawable/ticket_item_divider"
android:dividerHeight="1dp"
tools:ignore="NestedWeights"
android:choiceMode="singleChoice"
android:clickable="true"
android:background="#drawable/title_transparent_bg">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/acceptButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="2dp"
android:layout_weight="1"
android:onClick="onClickAccept" />
<Button
android:id="#+id/addUpdateButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:onClick="onClickAddUpdate" />
</LinearLayout>
</LinearLayout>
notelist_item.xml (inflator)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/text_note_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#80FFFFFF"
android:orientation="vertical"
>
<TextView
android:id="#+id/text_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="#string/filler_string"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/text_item_color"
android:textSize="#dimen/big_text_item_size" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight=".70"
>
<TextView
android:id="#+id/text_note_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="#string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text_sub_item_color" />
<TextView
android:id="#+id/text_note_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="#string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text_sub_item_color" />
<TextView
android:id="#+id/text_note_by_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="#string/filler_string"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text_sub_item_color" />
</LinearLayout>
</LinearLayout>
I'm going to recommend you reorganize your code. Here are some general tips:
1) Keep your views like ListView in the Activity class. Don't try to inflate the view in your adapter class. So in your activity's onCreate() after setContentView() you should have something like:
ListView listView = (ListView) findViewById(R.id.listView);
2) Next you need to get the data that will be shown in the listview and store it in a list. I didn't see in your code where the data comes from, but let's just say it comes from a database. You should create something like an ArrayList and store the data that you want to show in the ListView in the ArrayList
3) Next you need to create an adapter and pass the list of data into the adapter.
4) Once this has been done the ListView now has an adapter that will supply data to it. If you've done everything correctly then the system will eventually call getView() automatically and your code inside that should run and render the view.
Not an exact solution, but hopefully this explanation will help you figure it out.